Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
16 changes: 5 additions & 11 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1824,10 +1824,6 @@ impl Client {
self.send_raw_bytes(buf).await
}

pub(crate) async fn handle_unimplemented(&self, tag: &str) {
log::debug!("Unhandled stanza: <{tag}>");
}

pub async fn set_passive(&self, passive: bool) -> Result<(), crate::request::IqError> {
use wacore::iq::passive::PassiveModeSpec;
self.execute(PassiveModeSpec::new(passive)).await
Expand Down Expand Up @@ -2556,7 +2552,7 @@ impl Client {
if want_snapshot { "true" } else { "false" },
);
if !want_snapshot {
builder = builder.attr("version", state.version.to_string());
builder = builder.attr("version", state.version);
}
collection_nodes.push(builder.build());
}
Expand Down Expand Up @@ -2769,7 +2765,7 @@ impl Client {
if want_snapshot { "true" } else { "false" },
);
if !want_snapshot {
collection_builder = collection_builder.attr("version", state.version.to_string());
collection_builder = collection_builder.attr("version", state.version);
}
let sync_node = NodeBuilder::new("sync")
.children([collection_builder.build()])
Expand Down Expand Up @@ -2977,7 +2973,7 @@ impl Client {

let collection_node = NodeBuilder::new("collection")
.attr("name", collection_name)
.attr("version", base_version.to_string())
.attr("version", base_version)
.attr("return_snapshot", "false")
.children([NodeBuilder::new("patch").bytes(patch_bytes).build()])
.build();
Expand Down Expand Up @@ -3547,7 +3543,7 @@ impl Client {
.attr("to", to)
.attr("type", "reaction")
.attr("id", &request_id)
.attr("server_id", server_id.to_string())
.attr("server_id", server_id)
.children([NodeBuilder::new("reaction").attr("code", reaction).build()])
.build();

Expand Down Expand Up @@ -4969,9 +4965,7 @@ mod tests {

// Create a node with a 't' attribute
let server_time = wacore::time::now_secs() + 10; // Server is 10 seconds ahead
let node = NodeBuilder::new("success")
.attr("t", server_time.to_string())
.build();
let node = NodeBuilder::new("success").attr("t", server_time).build();

// Update the offset
client.update_server_time_offset(&node.as_node_ref());
Expand Down
7 changes: 5 additions & 2 deletions src/client/sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ impl Client {
// Signal that offline sync is complete - post-login tasks are waiting for this.
// This mimics WhatsApp Web's offlineDeliveryEnd event.
// Use compare_exchange to ensure we only run this once (add_permits is NOT idempotent).
// Install the wider semaphore BEFORE flipping the flag so that any thread
// observing offline_sync_completed=true already sees the 64-permit semaphore.
// Readers that observe offline_sync_completed=true short-circuit without touching
// the semaphore (wait_for_offline_delivery_end returns early), so the ordering of
// flag flip vs. semaphore swap below is not observable: any in-flight worker keeps
// using its old 1-permit Arc and drains normally; newly-spawned workers pick up the
// 64-permit semaphore via read_message_semaphore().
if self
.offline_sync_completed
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
Expand Down
4 changes: 2 additions & 2 deletions src/features/newsletter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,9 @@ impl<'a> Newsletter<'a> {
count: u32,
before: Option<u64>,
) -> Result<Vec<NewsletterMessage>, anyhow::Error> {
let mut messages_node = NodeBuilder::new("messages").attr("count", count.to_string());
let mut messages_node = NodeBuilder::new("messages").attr("count", count);
if let Some(before_id) = before {
messages_node = messages_node.attr("before", before_id.to_string());
messages_node = messages_node.attr("before", before_id);
}

let iq = InfoQuery::get(
Expand Down
35 changes: 35 additions & 0 deletions src/handlers/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/// Extract the required `from` JID attribute from a `NodeRef`, or log a warning
/// and return from the enclosing function.
///
/// Handler functions across the crate share the exact same pattern: pull `from`,
/// bail out with a warning if it is missing. This macro collapses that five-line
/// `match` into one line while preserving the (optional) log target.
///
/// # Variants
///
/// * `require_from_jid!(node, "Context")` — warns without a target, then `return;`.
/// * `require_from_jid!(node, target: "Client/Foo", "Context")` — warns with target.
#[macro_export]
macro_rules! require_from_jid {
($node:expr, $context:literal) => {
match $node.attrs().optional_jid("from") {
Some(jid) => jid,
None => {
::log::warn!(concat!($context, " missing required 'from' attribute"));
return;
}
}
};
($node:expr, target: $target:literal, $context:literal) => {
match $node.attrs().optional_jid("from") {
Some(jid) => jid,
None => {
::log::warn!(
target: $target,
concat!($context, " missing required 'from' attribute"),
);
return;
}
}
};
}
3 changes: 2 additions & 1 deletion src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ pub mod call;
pub mod chatstate;
pub mod ib;
pub mod iq;
#[macro_use]
mod macros;
pub mod message;
pub mod notification;
pub mod presence;
pub mod receipt;
pub mod router;
pub mod traits;
pub mod unimplemented;
41 changes: 16 additions & 25 deletions src/handlers/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,7 @@ fn handle_digest_key(client: &Arc<Client>) {
/// WA Web defers this when offline. We process immediately because all cleanup
/// is local-only, and `ensure_e2e_sessions` self-defers via `wait_for_offline_delivery_end`.
async fn handle_identity_change(client: &Arc<Client>, node: &NodeRef<'_>) {
let Some(from_jid) = node.attrs().optional_jid("from") else {
warn!("Identity change notification missing 'from' attribute");
return;
};
let from_jid = crate::require_from_jid!(node, "Identity change notification");

// Only primary device identity changes matter
if from_jid.device != 0 {
Expand Down Expand Up @@ -530,13 +527,11 @@ async fn handle_account_sync_devices(
devices_node: &NodeRef<'_>,
) {
// Extract the "from" JID - this is the account the notification is about
let from_jid = match node.attrs().optional_jid("from") {
Some(jid) => jid,
None => {
warn!(target: "Client/AccountSync", "account_sync devices missing 'from' attribute");
return;
}
};
let from_jid = crate::require_from_jid!(
node,
target: "Client/AccountSync",
"account_sync devices"
);

// Get our own JIDs (PN and LID) to verify this is about our account
let device_snapshot = client.persistence_manager.get_device_snapshot().await;
Expand Down Expand Up @@ -869,13 +864,11 @@ async fn handle_business_notification(client: &Arc<Client>, node: &NodeRef<'_>)
/// </notification>
/// ```
fn handle_picture_notification(client: &Arc<Client>, node: &NodeRef<'_>) {
let from = match node.attrs().optional_jid("from") {
Some(jid) => jid,
None => {
warn!(target: "Client/Picture", "picture notification missing 'from' attribute");
return;
}
};
let from = crate::require_from_jid!(
node,
target: "Client/Picture",
"picture notification"
);

let timestamp = notification_timestamp(node);

Expand Down Expand Up @@ -959,13 +952,11 @@ fn handle_picture_notification(client: &Arc<Client>, node: &NodeRef<'_>) {
/// </notification>
/// ```
fn handle_status_notification(client: &Arc<Client>, node: &NodeRef<'_>) {
let from = match node.attrs().optional_jid("from") {
Some(jid) => jid,
None => {
warn!(target: "Client/Status", "status notification missing 'from' attribute");
return;
}
};
let from = crate::require_from_jid!(
node,
target: "Client/Status",
"status notification"
);

let timestamp = notification_timestamp(node);

Expand Down
54 changes: 0 additions & 54 deletions src/handlers/unimplemented.rs

This file was deleted.

10 changes: 5 additions & 5 deletions src/retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -860,13 +860,13 @@ impl Client {
let mut retry_builder = NodeBuilder::new("retry")
.attr("v", "1")
.attr("id", info.id.clone())
.attr("t", info.timestamp.timestamp().to_string())
.attr("count", retry_count.to_string());
.attr("t", info.timestamp.timestamp())
.attr("count", retry_count);

// Include the error code if it's not UnknownError (matches WhatsApp Web's behavior
// where error is only included when there's a specific reason)
if reason != RetryReason::UnknownError {
retry_builder = retry_builder.attr("error", (reason as u8).to_string());
retry_builder = retry_builder.attr("error", reason as u8);
}

let retry_node = retry_builder.build();
Expand Down Expand Up @@ -1022,7 +1022,7 @@ impl Client {
let enc_rekey_node = NodeBuilder::new("enc_rekey")
.attr("call-creator", call_creator)
.attr("call-id", call_id)
.attr("count", retry_count.to_string())
.attr("count", retry_count)
.build();

let registration_node = NodeBuilder::new("registration")
Expand Down Expand Up @@ -1326,7 +1326,7 @@ mod tests {
let enc_rekey_node = NodeBuilder::new("enc_rekey")
.attr("call-creator", call_creator)
.attr("call-id", call_id)
.attr("count", retry_count.to_string())
.attr("count", retry_count)
.build();

let registration_node = NodeBuilder::new("registration")
Expand Down
3 changes: 0 additions & 3 deletions src/socket/noise_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ struct SendJob {
}

pub struct NoiseSocket {
#[allow(dead_code)] // Kept for potential future spawns
runtime: Arc<dyn Runtime>,
read_key: Arc<NoiseCipher>,
read_counter: Arc<AtomicU32>,
/// Channel to send jobs to the dedicated sender task.
Expand Down Expand Up @@ -60,7 +58,6 @@ impl NoiseSocket {
)));

Self {
runtime,
read_key,
read_counter: Arc::new(AtomicU32::new(0)),
send_job_tx,
Expand Down
4 changes: 1 addition & 3 deletions src/unified_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,7 @@ mod tests {
let manager = UnifiedSessionManager::new();

let server_time = wacore::time::now_secs() + 10;
let node = NodeBuilder::new("success")
.attr("t", server_time.to_string())
.build();
let node = NodeBuilder::new("success").attr("t", server_time).build();

manager.update_server_time_offset(&node.as_node_ref());

Expand Down
4 changes: 4 additions & 0 deletions wacore/binary/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ serde_json = { workspace = true, features = ["std"] }
[[bench]]
name = "binary_benchmark"
harness = false

[[bench]]
name = "numeric_attr_benchmark"
harness = false
Loading
Loading