docs(rust): add doc comments to delta enums and fix dead_code warnings (#24)

* docs(rust): add doc comments to delta enums and fix dead_code warnings

Add missing documentation to ProtocolDelta, CoreDelta, and BridgeDelta
enum variants and their struct fields across the protocol, core, and
bridge crates. Document the ChannelId::ROOT constant and the
take_delta_rx adapter method.

Fix dead_code warnings:
- keyring_disabled: add #[cfg] gate matching its callers
- snapshot_signature: add #[cfg(test)] for future test use

* fix(rust): correct `order` field docs to predecessor channel ID, narrow audio engine cfg gates

- Correct `order` field documentation in ProtocolDelta, SessionEvent,
  and BridgeEvent from 'sort order' to 'predecessor channel ID
  (TeamSpeak linked-list ordering hint)' per Copilot review feedback.
- Narrow AudioEngine voice_out_tx, voice_activity_selector, and mic_gain
  cfg gates from ios+macos+android to android-only, since these fields
  are only read from self in android_restart_voice_unit. On iOS/macOS the
  values are passed directly to the voice backend at construction time.
This commit is contained in:
Edison Jwa
2026-06-05 11:54:59 +09:00
committed by GitHub
parent d3bb199208
commit fb2a8e0a80
6 changed files with 130 additions and 6 deletions
+39
View File
@@ -253,49 +253,87 @@ pub enum SessionEvent {
},
/// Audio route changed (speaker/earpiece/BT/wired headset).
AudioRouteChanged {
/// New audio output route.
route: AudioRoute,
},
/// A client moved to a different channel.
ClientMoved {
/// Unique client identifier.
client_id: u64,
/// Destination channel.
new_channel_id: u64,
},
/// A new client connected.
ClientJoined {
/// Unique client identifier.
client_id: u64,
/// Channel the client joined.
channel_id: u64,
/// Display nickname.
name: String,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// Whether this is a server query (bot) client.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A client disconnected.
ClientLeft {
/// Unique client identifier.
client_id: u64,
/// Display nickname at time of disconnect.
name: String,
},
/// Client properties changed.
ClientUpdated {
/// Unique client identifier.
client_id: u64,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// Whether this is a server query (bot) client.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A new channel appeared.
ChannelAdded {
/// Unique channel identifier.
id: u64,
/// Parent channel ID.
parent: u64,
/// Channel name.
name: String,
/// Predecessor channel ID within the same parent (TeamSpeak
/// linked-list ordering hint). Zero means first child.
order: i64,
/// Whether the channel requires a password.
has_password: bool,
/// Talk power required to speak, or `None` when unrestricted.
needed_talk_power: Option<i32>,
},
/// A channel was deleted.
ChannelRemoved {
/// Channel identifier.
id: u64,
},
/// Channel properties changed.
ChannelUpdated {
/// Unique channel identifier.
id: u64,
/// Channel name.
name: String,
/// Whether the channel requires a password.
has_password: bool,
/// Talk power required to speak, or `None` when unrestricted.
needed_talk_power: Option<i32>,
},
}
@@ -2399,6 +2437,7 @@ async fn supervisor_loop(ctx: SupervisorContext) {
/// the UI would render. Two snapshots with identical channel
/// memberships, names, and orderings produce the same signature;
/// any in-channel move, rename, or reorder produces a different one.
#[cfg(test)]
fn snapshot_signature(snap: &ServerSnapshot) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
+3 -6
View File
@@ -306,11 +306,11 @@ pub struct AudioEngine {
audio_processing_config: Arc<Mutex<crate::AudioProcessingConfig>>,
audio_processing_stats: Arc<crate::SharedAudioProcessingStats>,
audio_handler: Arc<Mutex<AudioHandler<SessionAudioId>>>,
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
#[cfg(target_os = "android")]
voice_out_tx: mpsc::Sender<OutPacket>,
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
#[cfg(target_os = "android")]
voice_activity_selector: Option<Arc<crate::TransmitModeSelector>>,
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
#[cfg(target_os = "android")]
mic_gain: f32,
// Streams must be dropped to stop audio. Both are `!Send` because
// cpal's Stream isn't Send on some backends; we keep them in an
@@ -1308,9 +1308,6 @@ impl AudioEngine {
audio_processing_config,
audio_processing_stats,
audio_handler,
voice_out_tx,
voice_activity_selector: cfg.voice_activity_selector.clone(),
mic_gain: cfg.mic_gain,
_ios_voice_backend: Mutex::new(Some(ios_voice_backend)),
shutdown_tx: Some(shutdown_tx),
capture_active,
+38
View File
@@ -1701,49 +1701,87 @@ pub enum BridgeEvent {
},
/// Audio route changed (speaker/earpiece/BT/wired).
AudioRouteChanged {
/// New audio output route.
route: BridgeAudioRoute,
},
/// A client moved to a different channel.
ClientMoved {
/// Unique client identifier.
client_id: u64,
/// Destination channel.
new_channel_id: u64,
},
/// A new client connected.
ClientJoined {
/// Unique client identifier.
client_id: u64,
/// Channel the client joined.
channel_id: u64,
/// Display nickname.
name: String,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// True for server query (bot) clients.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A client disconnected.
ClientLeft {
/// Unique client identifier.
client_id: u64,
/// Display nickname at time of disconnect.
name: String,
},
/// Client properties changed.
ClientUpdated {
/// Unique client identifier.
client_id: u64,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// True for server query (bot) clients.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A new channel appeared.
ChannelAdded {
/// Unique channel identifier.
id: u64,
/// Parent channel ID.
parent: u64,
/// Channel name.
name: String,
/// Predecessor channel ID within the same parent (TeamSpeak
/// linked-list ordering hint). Zero means first child.
order: i64,
/// Whether the channel requires a password.
has_password: bool,
/// Talk power required to speak; `None` means no restriction.
needed_talk_power: Option<i32>,
},
/// A channel was deleted.
ChannelRemoved {
/// Channel identifier.
id: u64,
},
/// Channel properties changed.
ChannelUpdated {
/// Unique channel identifier.
id: u64,
/// Channel name.
name: String,
/// Whether the channel requires a password.
has_password: bool,
/// Talk power required to speak; `None` means no restriction.
needed_talk_power: Option<i32>,
},
}
+3
View File
@@ -471,6 +471,9 @@ impl ProtocolClient {
}
}
/// Takes ownership of the delta receiver channel. Returns `None` if already
/// taken. Must be called exactly once during initialization to subscribe to
/// incremental state changes.
pub fn take_delta_rx(&self) -> Option<mpsc::Receiver<ProtocolDelta>> {
self.delta_rx.lock().ok().and_then(|mut g| g.take())
}
+41
View File
@@ -168,52 +168,93 @@ pub struct ServerSnapshot {
}
impl ChannelId {
/// Root/top-level channel identifier.
pub const ROOT: ChannelId = ChannelId(0);
}
/// Incremental state change emitted by the protocol adapter when the server tree changes.
///
/// Covers client joins, leaves, moves, and channel additions, removals, and updates.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ProtocolDelta {
/// A client moved to a different channel.
ClientMoved {
/// Unique client identifier.
client_id: u64,
/// Destination channel identifier.
new_channel_id: u64,
},
/// A new client appeared on the server.
ClientJoined {
/// Unique client identifier.
client_id: u64,
/// Channel the client joined.
channel_id: u64,
/// Display nickname.
name: String,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// Whether the client is a server query client.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A client disconnected.
ClientLeft {
/// Unique client identifier.
client_id: u64,
/// Display nickname.
name: String,
},
/// A client's properties changed.
ClientUpdated {
/// Unique client identifier.
client_id: u64,
/// Microphone muted state.
input_muted: bool,
/// Speaker muted state.
output_muted: bool,
/// Whether the client is a server query client.
is_server_query: bool,
/// Client's talk power value.
talk_power: i32,
/// Whether the server granted temporary talk power.
talk_power_granted: bool,
},
/// A new channel appeared.
ChannelAdded {
/// Channel identifier.
id: u64,
/// Parent channel identifier.
parent: u64,
/// Channel name.
name: String,
/// Predecessor channel ID within the same parent (TeamSpeak
/// linked-list ordering hint). Zero means first child.
order: i64,
/// Whether the channel has a password.
has_password: bool,
/// Needed talk power, or `None` when unrestricted.
needed_talk_power: Option<i32>,
},
/// A channel was deleted.
ChannelRemoved {
/// Channel identifier.
id: u64,
},
/// Channel properties changed.
ChannelUpdated {
/// Channel identifier.
id: u64,
/// Channel name.
name: String,
/// Whether the channel has a password.
has_password: bool,
/// Needed talk power, or `None` when unrestricted.
needed_talk_power: Option<i32>,
},
}
+6
View File
@@ -628,6 +628,12 @@ fn read_file_dek(path: &Path) -> Result<[u8; 32], StorageError> {
/// headless / sandboxed environments force the file-fallback path
/// without poking a real OS keyring (which would either prompt the
/// user or block on a missing D-Bus session).
#[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "ios"
))]
fn keyring_disabled() -> bool {
matches!(
std::env::var("CHANORA_DISABLE_KEYRING").as_deref(),