Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions connect/src/spirc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
authentication::Credentials,
dealer::{
manager::{BoxedStream, BoxedStreamResult, Reply, RequestReply},
protocol::{Command, Message, Request},
protocol::{Command, FallbackWrapper, Message, Request},
},
session::UserAttributes,
Error, Session, SpotifyId,
Expand Down Expand Up @@ -81,7 +81,7 @@ struct SpircTask {
connect_state_volume_update: BoxedStreamResult<SetVolumeCommand>,
connect_state_logout_request: BoxedStreamResult<LogoutCommand>,
playlist_update: BoxedStreamResult<PlaylistModificationInfo>,
session_update: BoxedStreamResult<SessionUpdate>,
session_update: BoxedStreamResult<FallbackWrapper<SessionUpdate>>,
connect_state_command: BoxedStream<RequestReply>,
user_attributes_update: BoxedStreamResult<UserAttributesUpdate>,
user_attributes_mutation: BoxedStreamResult<UserAttributesMutation>,
Expand Down Expand Up @@ -191,7 +191,7 @@ impl Spirc {

let session_update = session
.dealer()
.listen_for("social-connect/v2/session_update", Message::from_json)?;
.listen_for("social-connect/v2/session_update", Message::try_from_json)?;

let user_attributes_update = session
.dealer()
Expand Down Expand Up @@ -1552,7 +1552,24 @@ impl SpircTask {
Ok(())
}

fn handle_session_update(&mut self, mut session_update: SessionUpdate) {
fn handle_session_update(&mut self, session_update: FallbackWrapper<SessionUpdate>) {
// we know that this enum value isn't present in our current proto definitions, by that
// the json parsing fails because the enum isn't known as proto representation
const WBC: &str = "WIFI_BROADCAST_CHANGED";

let mut session_update = match session_update {
FallbackWrapper::Inner(update) => update,
FallbackWrapper::Fallback(value) => {
let fallback_inner = value.to_string();
if fallback_inner.contains(WBC) {
Comment thread
photovoltex marked this conversation as resolved.
log::debug!("Received SessionUpdate::{WBC}");
} else {
log::warn!("SessionUpdate couldn't be parse correctly: {value:?}");
}
return;
}
};

let reason = session_update.reason.enum_value();

let mut session = match session_update.session.take() {
Expand Down
2 changes: 1 addition & 1 deletion core/src/dealer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ impl DealerShared {
}
}

warn!("No subscriber for msg.uri: {}", msg.uri);
debug!("No subscriber for msg.uri: {}", msg.uri);
}

fn dispatch_request(
Expand Down
25 changes: 13 additions & 12 deletions core/src/dealer/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ pub use request::*;
use std::collections::HashMap;
use std::io::{Error as IoError, Read};

use crate::Error;
use base64::prelude::BASE64_STANDARD;
use base64::{DecodeError, Engine};
use crate::{deserialize_with::json_proto, Error};
use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};
use flate2::read::GzDecoder;
use log::LevelFilter;
use serde::Deserialize;
Expand Down Expand Up @@ -99,17 +98,19 @@ pub struct Message {
pub uri: String,
}

#[derive(Deserialize)]
#[serde(untagged)]
pub enum FallbackWrapper<T: protobuf::MessageFull> {
Inner(#[serde(deserialize_with = "json_proto")] T),
Fallback(JsonValue),
}

impl Message {
pub fn from_json<M: protobuf::MessageFull>(value: Self) -> Result<M, Error> {
use protobuf_json_mapping::*;
pub fn try_from_json<M: protobuf::MessageFull>(
value: Self,
) -> Result<FallbackWrapper<M>, Error> {
match value.payload {
PayloadValue::Json(json) => match parse_from_str::<M>(&json) {
Ok(message) => Ok(message),
Err(_) => match parse_from_str_with_options(&json, &IGNORE_UNKNOWN) {
Ok(message) => Ok(message),
Err(why) => Err(Error::failed_precondition(why)),
},
},
PayloadValue::Json(json) => Ok(serde_json::from_str(&json)?),
other => Err(ProtocolError::UnexpectedData(other).into()),
}
}
Expand Down
6 changes: 1 addition & 5 deletions core/src/deserialize_with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ where
D: Deserializer<'de>,
{
let v: Value = Deserialize::deserialize(de)?;
parse_value_to_msg(&v).map_err(|why| {
warn!("deserialize_json_proto: {v}");
error!("deserialize_json_proto: {why}");
Error::custom(why)
})
parse_value_to_msg(&v).map_err(Error::custom)
}

pub fn option_json_proto<'de, T, D>(de: D) -> Result<Option<T>, D::Error>
Expand Down
Loading