Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/business.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ if let Some(profile) = client.get_business_profile(&jid).await? {
### BusinessProfile

```rust
#[non_exhaustive]
pub struct BusinessProfile {
pub wid: Option<Jid>,
pub description: String,
Expand All @@ -92,27 +93,36 @@ pub struct BusinessProfile {
}
```

`BusinessProfile` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### BusinessCategory

```rust
#[non_exhaustive]
pub struct BusinessCategory {
pub id: String,
pub name: String,
}
```

`BusinessCategory` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### BusinessHours

```rust
#[non_exhaustive]
pub struct BusinessHours {
pub timezone: Option<String>,
pub business_config: Option<Vec<BusinessHoursConfig>>,
}
```

`BusinessHours` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### BusinessHoursConfig

```rust
#[non_exhaustive]
pub struct BusinessHoursConfig {
pub day_of_week: DayOfWeek,
pub mode: BusinessHourMode,
Expand All @@ -121,6 +131,8 @@ pub struct BusinessHoursConfig {
}
```

`BusinessHoursConfig` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### DayOfWeek

```rust
Expand Down
12 changes: 12 additions & 0 deletions api/community.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,16 @@ Result of creating a community.

```rust
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct CreateCommunityResult {
pub metadata: GroupMetadata,
}
```

The `metadata` field carries the full community parent metadata from the server, with the inline `description: Option<String>` already populated. See [`GroupMetadata`](/api/groups#groupmetadata) for the full field list.

`CreateCommunityResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

<Note>
Prior to v0.6 this struct exposed only `gid: Jid` and derived `PartialEq, Eq`. The `Eq` derives were dropped because `GroupMetadata` does not implement them.
</Note>
Expand All @@ -326,6 +329,7 @@ A subgroup within a community. Implements `PartialEq` and `Eq`.

```rust
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct CommunitySubgroup {
pub id: Jid,
pub subject: String,
Expand All @@ -335,6 +339,8 @@ pub struct CommunitySubgroup {
}
```

`CommunitySubgroup` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

**Fields:**
- `id` — Subgroup JID
- `subject` — Subgroup name
Expand All @@ -348,24 +354,30 @@ Result of linking subgroups to a community. Implements `PartialEq` and `Eq`.

```rust
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct LinkSubgroupsResult {
pub linked_jids: Vec<Jid>,
pub failed_groups: Vec<(Jid, u32)>,
}
```

`LinkSubgroupsResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### UnlinkSubgroupsResult

Result of unlinking subgroups from a community. Implements `PartialEq` and `Eq`.

```rust
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct UnlinkSubgroupsResult {
pub unlinked_jids: Vec<Jid>,
pub failed_groups: Vec<(Jid, u32)>,
}
```

`UnlinkSubgroupsResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### GroupType

Classification of a group within the community hierarchy. Implements `PartialEq` and `Eq`.
Expand Down
4 changes: 4 additions & 0 deletions api/contacts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ pub async fn get_user_info(
- `verified_name: Option<VerifiedName>` - Decoded verified business name certificate, for verified business accounts (see [`is_on_whatsapp`](#is_on_whatsapp) for field details)
- `devices: Vec<u16>` - Device IDs from the `<devices version="2">` sublist the same usync query returns (device `0` is the primary). Empty when the server omits the sublist — no extra request is needed.

<Note>
`UserInfo` is `#[non_exhaustive]`, so new fields may be added in future versions without a breaking change.
</Note>

**Example:**
```rust
let jids = vec![
Expand Down
12 changes: 11 additions & 1 deletion api/groups.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,7 @@ pub struct MembershipRequest {
Result of a participant change operation (add, remove, approve, reject).

```rust
#[non_exhaustive]
pub struct ParticipantChangeResponse {
pub jid: Jid,
pub status: Option<String>,
Expand All @@ -1310,6 +1311,10 @@ pub struct ParticipantChangeResponse {
}
```

<Note>
`ParticipantChangeResponse` is `#[non_exhaustive]`. Field reads are unaffected; only exhaustive struct destructuring from outside the crate requires adding `..`.
</Note>

`add_request` is populated when the server responds with HTTP 403 carrying an `<add_request>` child — that happens when a participant has privacy blocked direct adds and the inviter must send them a v4 invite link out-of-band. Since v0.6 the value is preserved instead of being dropped, so consumers can drive the v4 invite flow without parsing the raw IQ.

```rust
Expand Down Expand Up @@ -1381,11 +1386,16 @@ pub struct GroupProfilePicture {
Result of creating a group.

```rust
#[non_exhaustive]
pub struct CreateGroupResult {
pub metadata: GroupMetadata,
}
```

<Note>
`CreateGroupResult` is `#[non_exhaustive]`. Field reads are unaffected; only exhaustive struct destructuring from outside the crate requires adding `..`.
</Note>

The `metadata` field carries the full group state returned by the server (same shape as [`get_metadata`](#get_metadata)). `metadata.participants` is `Vec<GroupParticipant>` — note that masked-number `display_name` labels live on `GroupParticipantInfo` (which carries `<participant>` children of *notification* events), not on `GroupParticipant` here.

<Note>
Expand Down Expand Up @@ -1454,4 +1464,4 @@ match client.groups().set_subject(&group_jid, subject).await {
Ok(_) => println!("Subject updated"),
Err(e) => eprintln!("Failed to update subject: {}", e),
}
```
```
3 changes: 3 additions & 0 deletions api/send.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Result of a successfully sent message. Provides the message ID and a convenience

```rust
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct SendResult {
pub message_id: String,
pub to: Jid,
Expand All @@ -61,6 +62,8 @@ impl SendResult {
}
```

`SendResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### ChatMessageId

Identifies a specific message within a chat. Useful for operations that need both the chat and message ID together.
Expand Down
7 changes: 6 additions & 1 deletion api/upload.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub async fn upload(
Contains all metadata needed to include the media in a message:

```rust
#[non_exhaustive]
pub struct UploadResponse {
pub url: String,
pub direct_path: String,
Expand All @@ -68,6 +69,10 @@ pub async fn upload(
pub fn file_enc_sha256_vec(&self) -> Vec<u8> { ... }
}
```

<Note>
`UploadResponse` is `#[non_exhaustive]`. Field reads are unaffected; only exhaustive struct destructuring from outside the crate requires adding `..`.
</Note>

<ParamField path="url" type="String">
Full CDN URL where the encrypted file was uploaded
Expand Down Expand Up @@ -240,7 +245,7 @@ client.send_message(chat_jid, msg).await?;
```

| Builder | Options struct | Notable fields (all optional) | MIME default |
|---------|----------------|-------------------------------|--------------|
|---------|----------------|-------------------------------|-------------|
| `media::image_message(upload, opts)` | `ImageOptions` | `caption`, `mimetype`, `jpeg_thumbnail` | `image/jpeg` |
| `media::video_message(upload, opts)` | `VideoOptions` | `caption`, `mimetype`, `jpeg_thumbnail`, `duration_seconds`, `gif_playback` | `video/mp4` |
| `media::document_message(upload, opts)` | `DocumentOptions` | `mimetype`, `file_name`, `title`, `caption`, `page_count`, `jpeg_thumbnail` | `application/octet-stream` |
Expand Down
36 changes: 36 additions & 0 deletions changelog/2026-06-09-non-exhaustive.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: "June 9, 2026 — Response structs marked #[non_exhaustive]"
description: "All library-returned response and result structs are now #[non_exhaustive], completing the pre-1.0 API stabilisation pass."
---

## Breaking changes

**Response and result structs are `#[non_exhaustive]` ([#794](https://github.com/oxidezap/whatsapp-rust/pull/794))**

`#[non_exhaustive]` has been applied to all public structs the library returns to consumers but never requires consumers to construct. `IsOnWhatsAppResult` already carried the attribute; this pass extends it to the remaining types before 1.0, while adding new fields is still cheap.

**Affected types:**

*wacore:*
- `UserInfo`, `LidQueryResponse`
- `BusinessProfile`, `BusinessHours`, `BusinessHoursConfig`, `BusinessCategory`
- `GroupInfoResponse`, `GroupParticipantResponse`, `GroupParticipatingResponse`, `ParticipantChangeResponse`

*whatsapp-rust:*
- `SendResult`, `UploadResponse`
- `CreateGroupResult`
- `CreateCommunityResult`, `CommunitySubgroup`, `LinkSubgroupsResult`, `UnlinkSubgroupsResult`

**What changes:** External crates can no longer construct these types via struct-literal syntax or match them exhaustively without a `..` wildcard. Field reads are unaffected.

**In practice:** The library constructs all of these — consumers only receive them. The PR confirmed zero struct-literal constructions outside the defining crate, so the attribute enforces the already-intended API contract.

**Migration:** Add `..` to any exhaustive struct destructuring patterns:

```rust
// Before (fails to compile outside the crate):
let SendResult { message_id, to } = result;

// After:
let SendResult { message_id, to, .. } = result;
```
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"pages": [
"changelog/overview",
"changelog/2026-06-09",
"changelog/2026-06-09-non-exhaustive",
"changelog/2026-06-08",
"changelog/2026-06-06",
"changelog/2026-06-05-abprops",
Expand Down