1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// SPDX-License-Identifier: MPL-2.0
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! Subscription system for device state changes.
//!
//! This module provides a callback-based subscription system for receiving
//! notifications when device state changes. It is designed for MQTT devices
//! which maintain persistent connections and receive real-time updates.
//!
//! # Overview
//!
//! The subscription system consists of:
//!
//! - [`SubscriptionId`] - A unique identifier for a subscription, used to unsubscribe
//! - [`CallbackRegistry`] - Internal registry that manages callbacks and dispatches events
//! - [`Subscribable`] - Trait for types that support event subscriptions
//!
//! # Usage
//!
//! Subscriptions are typically created through methods on MQTT devices:
//!
//! ```no_run
//! use tasmor_lib::MqttBroker;
//! use tasmor_lib::subscription::Subscribable;
//!
//! # async fn example() -> tasmor_lib::Result<()> {
//! let broker = MqttBroker::builder()
//! .host("192.168.1.50")
//! .build()
//! .await?;
//!
//! let (device, _) = broker.device("tasmota_device")
//! .build()
//! .await?;
//!
//! // Subscribe to power state changes
//! let sub_id = device.on_power_changed(|index, state| {
//! println!("Power {index} changed to {state:?}");
//! });
//!
//! // Later, unsubscribe
//! device.unsubscribe(sub_id);
//! # Ok(())
//! # }
//! ```
//!
//! # HTTP vs MQTT
//!
//! - **HTTP devices**: Do not support subscriptions (stateless protocol)
//! - **MQTT devices**: Full subscription support via the [`Subscribable`] trait
//!
//! Attempting to call subscription methods on HTTP devices results in a compile-time error.
pub use ;
pub use Subscribable;