1#![doc = include_str!("../README.md")]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5#![recursion_limit = "512"]
9
10#[cfg(test)]
14#[allow(clippy::disallowed_types)]
15pub(crate) mod test_alloc {
16 use std::alloc::{GlobalAlloc, Layout, System};
17 use std::sync::atomic::{AtomicU64, Ordering};
18
19 pub(crate) static ALLOCS: AtomicU64 = AtomicU64::new(0);
20
21 struct CountingAlloc;
22
23 unsafe impl GlobalAlloc for CountingAlloc {
24 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
25 ALLOCS.fetch_add(1, Ordering::Relaxed);
26 unsafe { System.alloc(layout) }
27 }
28
29 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
30 unsafe { System.dealloc(ptr, layout) }
31 }
32 }
33
34 #[global_allocator]
35 static GLOBAL: CountingAlloc = CountingAlloc;
36
37 pub(crate) fn min_allocs<T>(expected: u64, mut op: impl FnMut() -> T) -> u64 {
48 const BUDGET: u32 = 100_000;
52
53 let mut min = u64::MAX;
54 for _ in 0..BUDGET {
55 let before = ALLOCS.load(Ordering::Relaxed);
56 let value = std::hint::black_box(op());
57 let after = ALLOCS.load(Ordering::Relaxed);
58 drop(value);
59 min = min.min(after - before);
60 if min <= expected {
61 break;
62 }
63 }
64 min
65 }
66}
67
68pub use wacore::appstate::schemas;
69pub use wacore::client_profile::ClientProfile;
70pub use wacore::telemetry;
72pub use wacore::{
73 iq::privacy as privacy_settings, proto_helpers, sticker_pack, store::traits, webp,
74};
75pub use wacore_binary::CompactString;
76pub use wacore_binary::OwnedNodeRef;
77pub use wacore_binary::builder::NodeBuilder;
78pub use wacore_binary::{Jid, Server};
79
80pub use wacore;
84pub use wacore_binary;
85pub use waproto;
86
87pub use anyhow;
91pub use async_channel;
92pub use async_trait::async_trait;
93pub use bytes;
94pub use futures;
95pub use serde;
96pub use serde_json;
97pub use wacore::chrono;
98pub use waproto::buffa;
99
100pub mod cache;
101pub use cache::Freshness;
102pub mod portable_cache;
103pub(crate) mod resend_rate_limiter;
104
105pub mod cache_config;
106pub use cache_config::{
107 CacheConfig, CacheEntryConfig, CacheStores, MsgSecretPolicy, MsgSecretRetention,
108 OriginalMessageResolver,
109};
110pub mod cache_store;
111pub(crate) mod pending_device_sync;
112pub(crate) mod sender_key_device_cache;
113pub use cache_store::CacheStore;
114pub mod http;
115pub mod types;
116
117pub mod client;
118pub(crate) mod flush_scope;
119pub use client::ClientError;
122pub use client::NodeFilter;
123pub use client::{
124 AllocSnapshot, CollectionStats, HttpResourceReport, MemoryReport, ResourceReport,
125 StatsSnapshot, StorageResourceReport, TransportResourceReport,
126};
127pub use client::{CallError, Voip};
128pub use client::{Client, ClientBuild, ClientBuilder, ClientBuilderError, RawNodeLease};
129#[cfg(feature = "client-lifecycle")]
130#[cfg_attr(docsrs, doc(cfg(feature = "client-lifecycle")))]
131pub use client::{ClientLifecycle, ConnectionScope, ConnectionScopeState};
132pub use client::{ConnectError, ConnectStage, SignalMaintenanceError};
133pub use types::durability_hook::InboundDurabilityHook;
134pub use types::retry_admission::RetryAdmission;
135pub mod download;
136pub mod error;
137pub use error::{ErrorChainExt, ServerRejection, Sources};
138pub mod handlers;
139pub use handlers::chatstate::ChatStateEvent;
140pub mod handshake;
141pub mod jid_utils;
142pub mod keepalive;
143pub mod mediaconn;
144pub mod message;
145pub(crate) mod msg_secret_buffer;
146pub mod pair;
147pub mod pair_code;
148pub mod passkey;
149#[cfg(feature = "plugins")]
150#[cfg_attr(docsrs, doc(cfg(feature = "plugins")))]
151pub mod plugins;
152#[cfg(feature = "plugins")]
153#[cfg_attr(docsrs, doc(cfg(feature = "plugins")))]
154pub use plugins::{
155 ClientPlugin, PluginCapabilities, PluginCapability, PluginConnectionScope,
156 PluginConnectionTasks, PluginContext, PluginCoreEventSubscription, PluginCoreEvents,
157 PluginEventEndpointConfig, PluginEventEndpointStats, PluginEventEnvelope, PluginEventOverflow,
158 PluginEventPayloadEncoding, PluginEventPublishError, PluginEventPublishReport,
159 PluginEventPublisherStats, PluginEventReceiveError, PluginEventRouteError, PluginEventRouter,
160 PluginEventRouterStats, PluginEventSelector, PluginEventSubscribeError,
161 PluginEventSubscription, PluginEventTopic, PluginEventTryReceiveError, PluginEvents,
162 PluginFuture, PluginHealth, PluginHostConfig, PluginHostStats, PluginIq, PluginIqError,
163 PluginManifest, PluginMessaging, PluginMessagingError, PluginPlanError, PluginResourceError,
164 PluginState, PluginStats, PluginTasks, UntypedClientPlugin,
165};
166pub mod request;
167pub(crate) mod signal_flush;
168pub use request::IqError;
169#[cfg(feature = "tokio-runtime")]
170pub mod runtime_impl;
171#[cfg(feature = "tokio-runtime")]
172pub use runtime_impl::TokioRuntime;
173pub use wacore::runtime::Runtime;
174pub mod send;
175pub use send::{EditOptions, PinDuration, RevokeType, SendError, SendOptions, SendResult};
176pub use wacore::send::StanzaType;
177pub mod media;
178pub mod session;
179pub mod socket;
180pub mod store;
181pub mod transport;
182pub mod upload;
183#[cfg(feature = "voip-runtime")]
184pub mod voip;
185pub use upload::UploadOptions;
186
187pub mod pdo;
188pub mod prekeys;
189pub mod receipt;
190pub mod retry;
191pub mod unified_session;
192
193pub mod appstate_sync;
194pub mod history_sync;
195pub mod usync;
196
197pub mod features;
198pub use features::{
199 AppStateError, BatchGroupResult, Blocking, BlockingError, BlocklistEntry, ChatActions,
200 ChatStateError, ChatStateType, Chatstate, Comments, Community, CommunityError,
201 CommunitySubgroup, ContactError, Contacts, CreateCommunityOptions, CreateCommunityResult,
202 CreateGroupResult, EncType, EncryptedEdit, EventCreationParams, EventResponseType, Events,
203 GroupAppealStatus, GroupCreateOptions, GroupDescription, GroupEphemeralSettings, GroupError,
204 GroupJoinError, GroupMetadata, GroupParticipant, GroupParticipantDetails,
205 GroupParticipantOptions, GroupProfilePicture, GroupSubject, GroupType, Groups, GrowthLockInfo,
206 InviteInfoError, IsOnWhatsAppResult, JoinGroupResult, Labels, LinkSubgroupsResult,
207 MediaRetryResult, MediaReupload, MediaReuploadError, MediaReuploadRequest, MemberAddMode,
208 MemberLinkMode, MemberShareHistoryMode, MembershipApprovalMode, MembershipRequest,
209 MessageEditError, MessageRetransmission, Mex, MexError, MexErrorExtensions, MexGraphQLError,
210 MexRequest, MexResponse, NackReason, Newsletter, NewsletterError, NewsletterMessage,
211 NewsletterMessageType, NewsletterMetadata, NewsletterReactionCount, NewsletterRole,
212 NewsletterState, NewsletterVerification, ParticipantChangeResponse, ParticipantType,
213 PictureType, PollError, PollOptionResult, PollVoteCiphertext, Polls, Presence, PresenceError,
214 PresenceStatus, PreviousDescription, Profile, ProfileError, ProfilePicture, ReachoutTimelock,
215 RetryReason, RetryRequestError, RetryRequestOptions, RetryRequestOutcome, SecretEncKind,
216 SecretEncrypted, SetProfilePictureResponse, Signal, SignalError, SignalSessionInfo,
217 SignalSessionMigration, StanzaRejection, StanzaResponseError, Status, StatusPrivacySetting,
218 StatusSendOptions, SyncActionMessageRange, TcToken, TcTokenError, UnlinkSubgroupsResult,
219 UserInfo, UsyncSubprotocolError, VerifiedName, group_type, message_key, message_range,
220};
221
222pub mod bot;
223pub mod lid_pn_cache;
224#[cfg(feature = "signal")]
225pub mod shutdown;
226#[cfg(feature = "signal")]
227pub use shutdown::shutdown_signal;
228pub mod spam_report;
229pub mod sync_task;
230pub mod version;
231
232pub mod prelude {
235 pub use crate::bot::{Bot, BotBuilder, BotHandle, EventDelivery, MessageContext};
236 pub use crate::client::{Client, ClientBuilder, ClientBuilderError, ClientError, RawNodeLease};
237 #[cfg(feature = "client-lifecycle")]
238 #[cfg_attr(docsrs, doc(cfg(feature = "client-lifecycle")))]
239 pub use crate::client::{ClientLifecycle, ConnectionScope, ConnectionScopeState};
240 pub use crate::client::{ConnectError, ConnectStage};
241 #[cfg(feature = "plugins")]
242 #[cfg_attr(docsrs, doc(cfg(feature = "plugins")))]
243 pub use crate::plugins::{
244 ClientPlugin, PluginCapability, PluginConnectionScope, PluginContext,
245 PluginCoreEventSubscription, PluginEventEndpointConfig, PluginEventOverflow,
246 PluginEventPayloadEncoding, PluginEventRouter, PluginEventSelector,
247 PluginEventSubscription, PluginEventTopic, PluginEvents, PluginFuture, PluginHostConfig,
248 PluginManifest, UntypedClientPlugin,
249 };
250 pub use crate::request::IqError;
251 #[cfg(feature = "tokio-runtime")]
252 pub use crate::runtime_impl::TokioRuntime;
253 pub use crate::send::{EditOptions, SendError, SendOptions, SendResult};
254 #[cfg(feature = "signal")]
255 pub use crate::shutdown::shutdown_signal;
256 #[cfg(feature = "sqlite-storage")]
257 pub use crate::store::SqliteStore;
258 pub use crate::types::events::{
259 BatchOrigin, ChannelEventHandler, Event, EventHandler, EventInterest, EventKind,
260 InboundMessage, MessageBatch, Subscription,
261 };
262 pub use crate::types::message::MessageInfo;
263 pub use crate::{Jid, Server};
264 pub use wacore::proto_helpers::{MessageBuilderExt, MessageExt};
265 pub use waproto::buffa::MessageField;
267 pub use waproto::whatsapp as wa;
269}
270
271pub use spam_report::{SpamFlow, SpamReportRequest, SpamReportResult};
272
273#[cfg(test)]
274pub mod test_utils;
275
276#[cfg(test)]
277mod reexports_test;