diff --git a/ubisync-lib/src/messages/mod.rs b/ubisync-lib/src/messages/mod.rs index 9e4f3cc..679f897 100644 --- a/ubisync-lib/src/messages/mod.rs +++ b/ubisync-lib/src/messages/mod.rs @@ -24,7 +24,7 @@ pub enum MessageContent { content: ElementContent, pot: PotId, }, - SetElement { + UpdateElement { id: ElementId, content: ElementContent, }, diff --git a/ubisync-lib/src/types/element.rs b/ubisync-lib/src/types/element.rs index 4b90443..7291b7b 100644 --- a/ubisync-lib/src/types/element.rs +++ b/ubisync-lib/src/types/element.rs @@ -5,33 +5,22 @@ use super::{ElementContent, ElementId, MessageId, PotId}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct Element { // Uuid identifying the element itself - id: ElementId, - pot: Option, - content: ElementContent, - latest_message: Option, - local_changes: bool, -} - - -impl From<(ElementId, Option, ElementContent, Option, bool)> for Element { - fn from(value: (ElementId, Option, ElementContent, Option, bool)) -> Self { - Element { - id: value.0, - pot: value.1, - content: value.2, - latest_message: value.3, - local_changes: value.4, - } - } + pub id: ElementId, + pub pot: Option, + pub content: ElementContent, + pub update_strategy: ElementUpdateStrategy, + pub latest_message: Option, + pub local_changes: bool, } impl Element { - pub fn new(id: ElementId, content: ElementContent) -> Self { + pub fn new(id: ElementId, content: ElementContent, update_strategy: ElementUpdateStrategy) -> Self { // A new element with no latest message must have local changes Element { id: id, pot: None, - content: content, + content, + update_strategy, latest_message: None, local_changes: true, } @@ -53,3 +42,16 @@ impl Element { self.local_changes } } + + + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum ElementUpdateStrategy { + Overwrite +} + +impl Default for ElementUpdateStrategy { + fn default() -> Self { + Self::Overwrite + } +} \ No newline at end of file diff --git a/ubisync-lib/src/types/mod.rs b/ubisync-lib/src/types/mod.rs index 8475e64..f256046 100644 --- a/ubisync-lib/src/types/mod.rs +++ b/ubisync-lib/src/types/mod.rs @@ -8,7 +8,7 @@ mod element_id; pub use element_id::ElementId; mod element; -pub use element::Element; +pub use element::{Element, ElementUpdateStrategy}; mod family_id; pub use family_id::FamilyId; diff --git a/ubisync/src/comm/message_processor.rs b/ubisync/src/comm/message_processor.rs index 6627b0a..231b349 100644 --- a/ubisync/src/comm/message_processor.rs +++ b/ubisync/src/comm/message_processor.rs @@ -1,7 +1,7 @@ use tracing::debug; use ubisync_lib::peer::Peer; -use ubisync_lib::types::PeerId; +use ubisync_lib::types::{ElementUpdateStrategy, PeerId}; use ubisync_lib::messages::{Message, MessageContent}; @@ -20,12 +20,13 @@ pub fn handle(state: &CommState, peer: &PeerId, message: Message) { .add_received_element( id.to_owned(), content.to_owned(), + ElementUpdateStrategy::Overwrite, Some(message.id().to_owned()), pot.to_owned(), ) .expect("State failed"); } - MessageContent::SetElement { id, content } => { + MessageContent::UpdateElement { id, content } => { state .update_element_content(id.to_owned(), content.to_owned(), message.id().to_owned()) .expect("State failed"); diff --git a/ubisync/src/state/api_state.rs b/ubisync/src/state/api_state.rs index 6a52b4c..0e7aead 100644 --- a/ubisync/src/state/api_state.rs +++ b/ubisync/src/state/api_state.rs @@ -6,7 +6,7 @@ use tracing::debug; use ubisync_lib::{ api::events::AppEvent, messages::MessageContent, - types::{AppId, Element, ElementContent, ElementId, Pot, PotId}, + types::{AppId, Element, ElementContent, ElementId, ElementUpdateStrategy, Pot, PotId}, }; use crate::api::v0::app::App; @@ -60,7 +60,7 @@ impl ApiState { pub fn create_element(&self, content: ElementContent, pot: PotId) -> anyhow::Result { let id = ElementId::new(); self.db() - .add_element(id.clone(), content.clone(), None, false, pot.clone())?; + .add_element(id.clone(), content.clone(), ElementUpdateStrategy::Overwrite, None, false, pot.clone())?; debug!("Added element {{{}}}", id.to_string()); self.state.send_to_peers( diff --git a/ubisync/src/state/comm_state.rs b/ubisync/src/state/comm_state.rs index ccb984b..5c0d442 100644 --- a/ubisync/src/state/comm_state.rs +++ b/ubisync/src/state/comm_state.rs @@ -5,7 +5,7 @@ use tracing::debug; use ubisync_lib::{ api::events::AppEvent, peer::Peer, - types::{Element, ElementContent, ElementId, MessageId, PotId}, + types::{Element, ElementContent, ElementId, ElementUpdateStrategy, MessageId, PotId}, }; use crate::node_events::UbisyncNodeEvent; @@ -25,11 +25,19 @@ impl CommState { &self, id: ElementId, content: ElementContent, + update_strategy: ElementUpdateStrategy, latest_message: Option, pot_id: PotId, ) -> anyhow::Result<()> { self.db() - .add_element(id.clone(), content, latest_message, false, pot_id) + .add_element( + id.clone(), + content, + update_strategy, + latest_message, + false, + pot_id, + ) .inspect(|_| debug!("Added element {{{}}}", id.to_string())) } @@ -102,7 +110,7 @@ mod tests { use super::CommState; use tracing::Level; - use ubisync_lib::types::{ElementContent, ElementId, MessageId, PotId}; + use ubisync_lib::types::{ElementContent, ElementId, ElementUpdateStrategy, MessageId, PotId}; #[tokio::test] #[serial_test::serial] @@ -119,6 +127,7 @@ mod tests { .add_received_element( id.clone(), ElementContent::Text("Test-text".to_string()), + ElementUpdateStrategy::Overwrite, Some(MessageId::new()), pot_id, ) @@ -145,6 +154,7 @@ mod tests { .add_received_element( id.clone(), ElementContent::Text("Test-text".to_string()), + ElementUpdateStrategy::Overwrite, Some(MessageId::new()), pot_id, ) diff --git a/ubisync/src/state/database/collections/apps.rs b/ubisync/src/state/database/collections/apps.rs index 5cb5b49..678727d 100644 --- a/ubisync/src/state/database/collections/apps.rs +++ b/ubisync/src/state/database/collections/apps.rs @@ -113,7 +113,7 @@ impl StateDB { #[cfg(test)] mod tests { - use ubisync_lib::types::{AppId, ElementContent, ElementId, Pot, PotId}; + use ubisync_lib::types::{AppId, ElementContent, ElementId, ElementUpdateStrategy, Pot, PotId}; use crate::{api::v0::app::App, state::database::StateDB}; @@ -259,6 +259,7 @@ mod tests { db.add_element( element_id.clone(), ElementContent::Text("Text".to_string()), + ElementUpdateStrategy::Overwrite, None, false, pot_id.clone(), diff --git a/ubisync/src/state/database/collections/elements.rs b/ubisync/src/state/database/collections/elements.rs index 4cd979c..9b24919 100644 --- a/ubisync/src/state/database/collections/elements.rs +++ b/ubisync/src/state/database/collections/elements.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Error}; use bonsaidb::core::schema::{Collection, SerializedCollection}; use serde::{Deserialize, Serialize}; -use ubisync_lib::types::{Element, ElementContent, ElementId, MessageId, PotId}; +use ubisync_lib::types::{Element, ElementContent, ElementId, ElementUpdateStrategy, MessageId, PotId}; use crate::state::database::{as_key::AsKey, StateDB}; @@ -11,6 +11,7 @@ pub(super) struct DbElement { #[natural_id] pub(super) id: AsKey, pub(super) content: ElementContent, + pub(super) update_strategy: ElementUpdateStrategy, pub(super) latest_message: Option, pub(super) local_changes: bool, pub(super) pot: PotId, @@ -18,13 +19,14 @@ pub(super) struct DbElement { impl From for Element { fn from(value: DbElement) -> Self { - Element::from(( - (*value.id).clone(), - Some(value.pot), - value.content, - value.latest_message, - value.local_changes, - )) + Element { + id: (*value.id).clone(), + content: value.content, + update_strategy: value.update_strategy, + latest_message: value.latest_message, + local_changes: value.local_changes, + pot: Some(value.pot), + } } } @@ -33,6 +35,7 @@ impl StateDB { &self, id: ElementId, content: ElementContent, + update_strategy: ElementUpdateStrategy, latest_message: Option, local_changes: bool, pot: PotId, @@ -41,6 +44,7 @@ impl StateDB { DbElement { id: AsKey::new(id), content, + update_strategy, latest_message, local_changes, pot, @@ -104,7 +108,7 @@ impl StateDB { #[cfg(test)] mod tests { - use ubisync_lib::types::{ElementContent, ElementId, MessageId, PotId}; + use ubisync_lib::types::{Element, ElementContent, ElementId, ElementUpdateStrategy, MessageId, PotId}; use crate::state::database::StateDB; @@ -116,6 +120,7 @@ mod tests { db.add_element( element_id.clone(), ElementContent::Text("Content!!!".to_string()), + ElementUpdateStrategy::default(), None, false, pot_id.clone(), @@ -126,14 +131,14 @@ mod tests { assert_eq!( Some( - ( - element_id, - Some(pot_id), - ElementContent::Text("Content!!!".to_string()), - None, - false - ) - .into() + Element { + id: element_id, + content: ElementContent::Text("Content!!!".to_string()), + update_strategy: ElementUpdateStrategy::default(), + latest_message: None, + local_changes: false, + pot: Some(pot_id), + } ), retrieved_element ) @@ -146,6 +151,7 @@ mod tests { db.add_element( element_id.clone(), ElementContent::Text("Content!!!".to_string()), + ElementUpdateStrategy::default(), None, false, PotId::new(), @@ -171,6 +177,7 @@ mod tests { db.add_element( element_id.clone(), ElementContent::Text("Content!!!".to_string()), + ElementUpdateStrategy::default(), None, false, PotId::new(), @@ -206,6 +213,7 @@ mod tests { db.add_element( element_id.clone(), ElementContent::Text("Content!!!".to_string()), + ElementUpdateStrategy::default(), None, false, PotId::new(), diff --git a/ubisync/src/state/mod.rs b/ubisync/src/state/mod.rs index 768f409..b9fef22 100644 --- a/ubisync/src/state/mod.rs +++ b/ubisync/src/state/mod.rs @@ -88,7 +88,7 @@ impl State { .inspect(|_| { //TODO: Get all peers interested in the element, e.g. because they subscribe to the element's pot, a share, etc. self.send_to_peers( - MessageContent::SetElement { + MessageContent::UpdateElement { id: element_id.clone(), content: content.clone(), },