sonos_state/lib.rs
1//! Internal implementation detail of [`sonos-sdk`](https://crates.io/crates/sonos-sdk). Not intended for direct use.
2//!
3//! Sonos State Management
4//!
5//! A sync-first state management system for Sonos devices.
6//!
7//! # Features
8//!
9//! - **Sync API**: All operations are synchronous - no async/await required
10//! - **Type-safe State**: Strongly typed properties with automatic change detection
11//! - **Change Events**: Blocking iterator over property changes
12//! - **Watch Pattern**: Register for property changes, iterate to receive them
13//!
14//! # Quick Start
15//!
16//! ```rust,ignore
17//! use sonos_state::{StateManager, Volume, SpeakerId};
18//! use sonos_discovery;
19//!
20//! // Create state manager (sync - no .await!)
21//! let manager = StateManager::new()?;
22//!
23//! // Add discovered devices
24//! let devices = sonos_discovery::get();
25//! manager.add_devices(devices)?;
26//!
27//! // Get current property value
28//! let speaker_id = SpeakerId::new("RINCON_123");
29//! if let Some(vol) = manager.get_property::<Volume>(&speaker_id) {
30//! println!("Current volume: {}%", vol.0);
31//! }
32//!
33//! // Watch for changes
34//! manager.register_watch(&speaker_id, "volume");
35//!
36//! // Blocking iteration over changes
37//! for event in manager.iter() {
38//! println!("{} changed on {}", event.property_key, event.speaker_id);
39//! if let Some(vol) = manager.get_property::<Volume>(&event.speaker_id) {
40//! println!("New volume: {}%", vol.0);
41//! }
42//! }
43//! ```
44//!
45//! # Non-blocking Iteration
46//!
47//! ```rust,ignore
48//! // Check for events without blocking
49//! for event in manager.iter().try_iter() {
50//! println!("Event: {:?}", event);
51//! }
52//!
53//! // Wait with timeout
54//! if let Some(event) = manager.iter().recv_timeout(Duration::from_secs(1)) {
55//! println!("Got event: {:?}", event);
56//! }
57//! ```
58
59// This workspace contains no `unsafe` code. Asserted here so a future
60// addition is a hard compile error, not a silent change in guarantees.
61#![forbid(unsafe_code)]
62
63// Core modules
64pub mod model;
65pub mod property;
66
67// Event decoding
68pub mod decoder;
69
70// Event processing
71pub(crate) mod event_worker;
72
73// Sync-first API
74pub mod iter;
75pub mod speaker;
76pub mod state;
77
78// Error types
79pub mod error;
80
81// ============================================================================
82// Re-exports - Main API
83// ============================================================================
84
85// State manager
86pub use state::{
87 ChangeEvent, ChangeSource, EventInitFn, StateManager, StateManagerBuilder, WriteOutcome,
88 WriteStamp,
89};
90
91// Change iterator
92pub use iter::ChangeIterator;
93
94// Properties
95pub use property::{
96 Bass, CurrentTrack, GroupInfo, GroupMembership, GroupMute, GroupVolume, GroupVolumeChangeable,
97 Loudness, Mute, PlaybackState, Position, Property, Scope, SonosProperty, Topology, Treble,
98 Volume,
99};
100
101// Model types
102pub use model::{GroupId, SpeakerId, SpeakerInfo};
103
104// Event decoder
105pub use decoder::{
106 decode_event, decode_topology_event, parse_track_metadata, DecodedChanges, PropertyChange,
107 TopologyChanges,
108};
109
110// Error types
111pub use error::{Result, StateError};
112
113// ============================================================================
114// Prelude
115// ============================================================================
116
117/// Commonly used types for convenient importing
118pub mod prelude {
119 // Properties
120 pub use crate::property::{
121 Bass, CurrentTrack, GroupMembership, GroupMute, GroupVolume, GroupVolumeChangeable,
122 Loudness, Mute, PlaybackState, Position, Property, Scope, Topology, Treble, Volume,
123 };
124
125 // Model types
126 pub use crate::model::{GroupId, SpeakerId, SpeakerInfo};
127
128 // State management
129 pub use crate::decoder::PropertyChange;
130 pub use crate::iter::ChangeIterator;
131 pub use crate::state::{ChangeEvent, ChangeSource, StateManager};
132
133 // Error types
134 pub use crate::error::{Result, StateError};
135}