feat(cast): expose whether a Chromecast discovery id is stable (#638)

The mDNS TXT id record is the Cast device UUID - stable across restarts
and renames, directly comparable to a DLNA UDN. When a device omits it,
discovery falls back to the mDNS fullname, which is derived from the
friendly name and silently detaches the moment the user renames the
speaker. The per-renderer quality cap (fix 4) must not be keyed on such
an id - a cap that silently stops applying is the failure mode #638
exists to eliminate - so DiscoveredDevice now says which case it is.

Additive field on the discovery DTO only; no behavior change for
existing consumers. Verified: the struct has a single construction site.

cc
This commit is contained in:
vicrodh committed 2026-07-20 15:22:38 -06:00
1 parent f450975675
commit cd928c92a1
1 file changed
+11 -2
+11 -2
View File
@@ -21,6 +21,13 @@ pub struct DiscoveredDevice {
pub model: String,
pub ip: String,
pub port: u16,
/// Whether `id` came from the mDNS TXT `id` record — the Cast device
/// UUID, stable across restarts and renames (comparable to a DLNA UDN).
/// When the record is absent, `id` falls back to the mDNS fullname,
/// which is derived from the friendly name and so DETACHES on rename:
/// callers must not persist per-device state keyed on an unstable id
/// (#638 fix 4 offers no quality cap for such devices).
pub id_is_stable: bool,
}
#[derive(Default)]
@@ -73,8 +80,9 @@ impl DeviceDiscovery {
match event {
ServiceEvent::ServiceResolved(info) => {
let fullname = info.get_fullname().to_string();
let id = info
.get_property_val_str("id")
let id_prop = info.get_property_val_str("id");
let id_is_stable = id_prop.is_some();
let id = id_prop
.unwrap_or_else(|| fullname.as_str())
.to_string();
let name = info
@@ -95,6 +103,7 @@ impl DeviceDiscovery {
model,
ip,
port: info.get_port(),
id_is_stable,
};
if let Ok(mut state) = state.lock() {