wrap update-item-array into an update-object on the wire; this allows to add other members in the future. the updates the peers see is not changed

This commit is contained in:
B. Petersen
2022-01-10 12:42:23 +01:00
committed by bjoern
parent 8c2ea0fa26
commit 42f9ef00b9
2 changed files with 54 additions and 11 deletions

View File

@@ -1163,8 +1163,10 @@ impl<'a> MimeFactory<'a> {
let json = self.msg.param.get(Param::Arg).unwrap_or_default(); let json = self.msg.param.get(Param::Arg).unwrap_or_default();
parts.push(context.build_status_update_part(json).await); parts.push(context.build_status_update_part(json).await);
} else if self.msg.viewtype == Viewtype::Webxdc { } else if self.msg.viewtype == Viewtype::Webxdc {
let json = context.get_webxdc_status_updates(self.msg.id, None).await?; let json = context
if json != "[]" { .render_webxdc_status_update_object(self.msg.id, None)
.await?;
if json != r#"{{"updates":[]}}"# {
parts.push(context.build_status_update_part(&json).await); parts.push(context.build_status_update_part(&json).await);
} }
} }

View File

@@ -61,6 +61,12 @@ impl rusqlite::types::ToSql for StatusUpdateId {
} }
} }
// Array of update items as sent on the wire.
#[derive(Debug, Deserialize)]
struct StatusUpdates {
updates: Vec<StatusUpdateItem>,
}
/// Update items as sent on the wire and as stored in the database. /// Update items as sent on the wire and as stored in the database.
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub(crate) struct StatusUpdateItem { pub(crate) struct StatusUpdateItem {
@@ -147,8 +153,11 @@ impl Context {
.set_cmd(SystemMessage::WebxdcStatusUpdate); .set_cmd(SystemMessage::WebxdcStatusUpdate);
status_update.param.set( status_update.param.set(
Param::Arg, Param::Arg,
self.get_webxdc_status_updates(instance_msg_id, Some(status_update_id)) self.render_webxdc_status_update_object(
.await?, instance_msg_id,
Some(status_update_id),
)
.await?,
); );
status_update.set_quote(self, Some(&instance)).await?; status_update.set_quote(self, Some(&instance)).await?;
let status_update_msg_id = let status_update_msg_id =
@@ -190,8 +199,8 @@ impl Context {
bail!("receive_status_update: status message has no parent.") bail!("receive_status_update: status message has no parent.")
}; };
let update_items: Vec<StatusUpdateItem> = serde_json::from_str(json)?; let updates: StatusUpdates = serde_json::from_str(json)?;
for update_item in update_items { for update_item in updates.updates {
let status_update_id = self let status_update_id = self
.create_status_update_record( .create_status_update_record(
instance.id, instance.id,
@@ -242,6 +251,18 @@ impl Context {
.await?; .await?;
Ok(format!("[{}]", json)) Ok(format!("[{}]", json))
} }
/// Render JSON-object for status updates as used on the wire.
pub(crate) async fn render_webxdc_status_update_object(
&self,
instance_msg_id: MsgId,
status_update_id: Option<StatusUpdateId>,
) -> Result<String> {
let updates_array = self
.get_webxdc_status_updates(instance_msg_id, status_update_id)
.await?;
Ok(format!(r#"{{"updates":{}}}"#, updates_array))
}
} }
async fn parse_webxdc_manifest(bytes: &[u8]) -> Result<WebxdcManifest> { async fn parse_webxdc_manifest(bytes: &[u8]) -> Result<WebxdcManifest> {
@@ -548,23 +569,30 @@ mod tests {
.await .await
.is_err()); // no json .is_err()); // no json
assert!(t assert!(t
.receive_status_update(instance.id, r#"[{"foo":"bar"}]"#) .receive_status_update(instance.id, r#"{"updada":[{"payload":{"foo":"bar"}}]}"#)
.await
.is_err()); // "updates" object missing
assert!(t
.receive_status_update(instance.id, r#"{"updates":[{"foo":"bar"}]}"#)
.await .await
.is_err()); // "payload" field missing .is_err()); // "payload" field missing
assert!(t assert!(t
.receive_status_update(instance.id, r#"{"payload":{"foo":"bar"}}"#) .receive_status_update(instance.id, r#"{"updates":{"payload":{"foo":"bar"}}}"#)
.await .await
.is_err()); // not an array .is_err()); // not an array
t.receive_status_update(instance.id, r#"[{"payload":{"foo":"bar"}}]"#) t.receive_status_update(instance.id, r#"{"updates":[{"payload":{"foo":"bar"}}]}"#)
.await?; .await?;
assert_eq!( assert_eq!(
t.get_webxdc_status_updates(instance.id, None).await?, t.get_webxdc_status_updates(instance.id, None).await?,
r#"[{"payload":{"foo":"bar"}}]"# r#"[{"payload":{"foo":"bar"}}]"#
); );
t.receive_status_update(instance.id, r#" [ {"payload" :42} , {"payload": 23} ] "#) t.receive_status_update(
.await?; instance.id,
r#" {"updates": [ {"payload" :42} , {"payload": 23} ] } "#,
)
.await?;
assert_eq!( assert_eq!(
t.get_webxdc_status_updates(instance.id, None).await?, t.get_webxdc_status_updates(instance.id, None).await?,
r#"[{"payload":{"foo":"bar"}}, r#"[{"payload":{"foo":"bar"}},
@@ -572,6 +600,19 @@ mod tests {
{"payload":23}]"# {"payload":23}]"#
); );
t.receive_status_update(
instance.id,
r#" {"updates": [ {"payload" :"ok", "future_item": "test"} ], "from": "future" } "#,
)
.await?; // ignore members that may be added in the future
assert_eq!(
t.get_webxdc_status_updates(instance.id, None).await?,
r#"[{"payload":{"foo":"bar"}},
{"payload":42},
{"payload":23},
{"payload":"ok"}]"#
);
Ok(()) Ok(())
} }