fix(qconnect): correct wire types for track_id (fixed32) and shuffle_seed (fixed32)

Server sends track_id as fixed32 (wire type 5) and shuffle_seed as
fixed32, but our structs declared them as int32 (wire type 0/varint),
causing decode failures on QueueState, TracksLoaded, and
RendererSetState messages.
This commit is contained in:
vicrodh committed 2026-02-21 17:29:47 -06:00
1 parent 4c7be7597d
commit 9e8dfd91e5
3 files changed
+36 -30

No files matched your search

+12 -6
View File
@@ -566,7 +566,7 @@ fn map_tracks_loaded(payload: QueueTracksLoadedMessage) -> Result<QueueServerEve
payload: json!({
"tracks": tracks,
"queue_position": optional_i32_to_u64(payload.queue_position)?,
"shuffle_seed": optional_i32_to_u64(payload.shuffle_seed)?,
"shuffle_seed": payload.shuffle_seed.map(|v| v as u64),
"shuffle_pivot_queue_item_id": optional_i32_to_u64(payload.shuffle_pivot_queue_item_id)?,
"shuffle_mode": payload.shuffle_mode.unwrap_or(false),
"autoplay_reset": payload.autoplay_reset.unwrap_or(false),
@@ -593,7 +593,7 @@ fn map_tracks_inserted(
payload: json!({
"tracks": tracks,
"insert_after": optional_i32_to_u64(payload.insert_after)?,
"shuffle_seed": optional_i32_to_u64(payload.shuffle_seed)?,
"shuffle_seed": payload.shuffle_seed.map(|v| v as u64),
"autoplay_reset": payload.autoplay_reset.unwrap_or(false),
"autoplay_loading": payload.autoplay_loading.unwrap_or(false)
}),
@@ -614,7 +614,7 @@ fn map_tracks_added(payload: QueueTracksAddedMessage) -> Result<QueueServerEvent
queue_version: queue_version_opt(payload.queue_version)?,
payload: json!({
"tracks": tracks,
"shuffle_seed": optional_i32_to_u64(payload.shuffle_seed)?,
"shuffle_seed": payload.shuffle_seed.map(|v| v as u64),
"autoplay_reset": payload.autoplay_reset.unwrap_or(false),
"autoplay_loading": payload.autoplay_loading.unwrap_or(false)
}),
@@ -671,7 +671,7 @@ fn map_shuffle_mode_set(payload: ShuffleModeSetMessage) -> Result<QueueServerEve
queue_version: queue_version_opt(payload.queue_version)?,
payload: json!({
"shuffle_mode": payload.shuffle_mode.unwrap_or(false),
"shuffle_seed": optional_i32_to_u64(payload.shuffle_seed)?,
"shuffle_seed": payload.shuffle_seed.map(|v| v as u64),
"shuffle_pivot_queue_item_id": optional_i32_to_u64(payload.shuffle_pivot_queue_item_id)?,
"autoplay_reset": payload.autoplay_reset.unwrap_or(false),
"autoplay_loading": payload.autoplay_loading.unwrap_or(false)
@@ -967,7 +967,9 @@ fn queue_track_to_json(
track: QueueTrack,
context_uuid: Option<&str>,
) -> Result<Value, ProtocolError> {
let track_id = required_i32_to_u64(track.track_id, "queue_track.track_id")?;
let track_id = track.track_id.map(|v| v as u64).ok_or_else(|| {
ProtocolError::InvalidPayload("missing required field 'queue_track.track_id'".to_string())
})?;
let queue_item_id =
optional_i32_to_u64_named(track.queue_item_id, "queue_track.queue_item_id")?
.unwrap_or(track_id);
@@ -980,7 +982,11 @@ fn queue_track_to_json(
}
fn queue_track_with_context_to_json(track: QueueTrackWithContext) -> Result<Value, ProtocolError> {
let track_id = required_i32_to_u64(track.track_id, "queue_track_with_context.track_id")?;
let track_id = track.track_id.map(|v| v as u64).ok_or_else(|| {
ProtocolError::InvalidPayload(
"missing required field 'queue_track_with_context.track_id'".to_string(),
)
})?;
let queue_item_id = optional_i32_to_u64_named(
track.queue_item_id,
"queue_track_with_context.queue_item_id",
+4 -4
View File
@@ -159,7 +159,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
}),
QueueCommandType::CtrlSrvrQueueAddTracks => {
let track_ids = required_i32_list(&command.payload, "track_ids")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
let autoplay_reset = optional_bool(&command.payload, "autoplay_reset", false);
let autoplay_loading =
@@ -182,7 +182,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
QueueCommandType::CtrlSrvrQueueLoadTracks => {
let track_ids = required_i32_list(&command.payload, "track_ids")?;
let queue_position = optional_i32(&command.payload, "queue_position")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
let shuffle_pivot_index = optional_i32(&command.payload, "shuffle_pivot_index")?;
let shuffle_mode = optional_bool(&command.payload, "shuffle_mode", false);
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
@@ -210,7 +210,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
QueueCommandType::CtrlSrvrQueueInsertTracks => {
let track_ids = required_i32_list(&command.payload, "track_ids")?;
let insert_after = optional_i32(&command.payload, "insert_after")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
let autoplay_reset = optional_bool(&command.payload, "autoplay_reset", false);
let autoplay_loading =
@@ -285,7 +285,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
}),
QueueCommandType::CtrlSrvrSetShuffleMode => {
let shuffle_mode = optional_bool(&command.payload, "shuffle_mode", false);
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?;
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
let shuffle_pivot_queue_item_id =
optional_i32(&command.payload, "shuffle_pivot_queue_item_id")?;
let autoplay_reset = optional_bool(&command.payload, "autoplay_reset", false);
@@ -84,16 +84,16 @@ pub struct ErrorMessage {
pub struct QueueTrack {
#[prost(int32, optional, tag = "1")]
pub queue_item_id: Option<i32>,
#[prost(int32, optional, tag = "2")]
pub track_id: Option<i32>,
#[prost(fixed32, optional, tag = "2")]
pub track_id: Option<u32>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct QueueTrackWithContext {
#[prost(int32, optional, tag = "1")]
pub queue_item_id: Option<i32>,
#[prost(int32, optional, tag = "2")]
pub track_id: Option<i32>,
#[prost(fixed32, optional, tag = "2")]
pub track_id: Option<u32>,
#[prost(bytes = "vec", optional, tag = "3")]
pub context_uuid: Option<Vec<u8>>,
}
@@ -233,8 +233,8 @@ pub struct QueueLoadTracksMessage {
pub track_ids: Vec<i32>,
#[prost(int32, optional, tag = "4")]
pub queue_position: Option<i32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "5")]
pub shuffle_seed: Option<u32>,
#[prost(int32, optional, tag = "6")]
pub shuffle_pivot_index: Option<i32>,
#[prost(bool, optional, tag = "7")]
@@ -257,8 +257,8 @@ pub struct QueueInsertTracksMessage {
pub track_ids: Vec<i32>,
#[prost(int32, optional, tag = "4")]
pub insert_after: Option<i32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "5")]
pub shuffle_seed: Option<u32>,
#[prost(bytes = "vec", optional, tag = "6")]
pub context_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "7")]
@@ -275,8 +275,8 @@ pub struct QueueAddTracksMessage {
pub action_uuid: Option<Vec<u8>>,
#[prost(int32, repeated, packed = "false", tag = "3")]
pub track_ids: Vec<i32>,
#[prost(int32, optional, tag = "4")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "4")]
pub shuffle_seed: Option<u32>,
#[prost(bytes = "vec", optional, tag = "5")]
pub context_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "6")]
@@ -323,8 +323,8 @@ pub struct SetShuffleModeMessage {
pub action_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "3")]
pub shuffle_mode: Option<bool>,
#[prost(int32, optional, tag = "4")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "4")]
pub shuffle_seed: Option<u32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_pivot_queue_item_id: Option<i32>,
#[prost(bool, optional, tag = "6")]
@@ -447,8 +447,8 @@ pub struct QueueTracksLoadedMessage {
pub tracks: Vec<QueueTrack>,
#[prost(int32, optional, tag = "4")]
pub queue_position: Option<i32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "5")]
pub shuffle_seed: Option<u32>,
#[prost(int32, optional, tag = "6")]
pub shuffle_pivot_queue_item_id: Option<i32>,
#[prost(bool, optional, tag = "7")]
@@ -473,8 +473,8 @@ pub struct QueueTracksInsertedMessage {
pub tracks: Vec<QueueTrack>,
#[prost(int32, optional, tag = "4")]
pub insert_after: Option<i32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "5")]
pub shuffle_seed: Option<u32>,
#[prost(bytes = "vec", optional, tag = "6")]
pub context_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "7")]
@@ -493,8 +493,8 @@ pub struct QueueTracksAddedMessage {
pub action_uuid: Option<Vec<u8>>,
#[prost(message, repeated, tag = "3")]
pub tracks: Vec<QueueTrack>,
#[prost(int32, optional, tag = "4")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "4")]
pub shuffle_seed: Option<u32>,
#[prost(bytes = "vec", optional, tag = "5")]
pub context_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "6")]
@@ -547,8 +547,8 @@ pub struct ShuffleModeSetMessage {
pub action_uuid: Option<Vec<u8>>,
#[prost(bool, optional, tag = "3")]
pub shuffle_mode: Option<bool>,
#[prost(int32, optional, tag = "4")]
pub shuffle_seed: Option<i32>,
#[prost(fixed32, optional, tag = "4")]
pub shuffle_seed: Option<u32>,
#[prost(int32, optional, tag = "5")]
pub shuffle_pivot_queue_item_id: Option<i32>,
#[prost(bool, optional, tag = "6")]