Split State in separate views for Api and CommHandle

- State changes can now be handled differently, depending on whether they were caused locallly (API) or by a remote peer (Comm)
- State functions have more readable names (`write...` and `update...` have similar meanings, but using different names helps readability in the respective (API/Comm) context)
This commit is contained in:
Philip (a-0) 2023-12-08 22:31:47 +01:00
parent 32bbe8a8ce
commit 98393b9bf6
16 changed files with 326 additions and 138 deletions

View file

@ -10,9 +10,14 @@ use self::types::{ElementContent, ElementId, Element, Tag};
pub mod types;
mod api_state;
mod comm_state;
mod queries;
mod schema;
pub use api_state::ApiState;
pub use comm_state::CommState;
pub struct State {
db: DbInstance,
comm_handle: RwLock<Option<Arc<CommHandle>>>,
@ -34,58 +39,37 @@ impl State {
*self.comm_handle.write().as_deref_mut().expect("Could not set state's CommHandle") = Some(handle);
}
// Create an element and add it to the database
pub fn create_element(&self, content: &ElementContent) -> anyhow::Result<ElementId> {
let id = ElementId::new();
queries::set_element(&self.db, &id, &content)?;
debug!("Created element with id {:?}: {:?}", &id, self.get_element(&id));
self.send_to_peers(MessageContent::CreateElement { id: id.clone(), content: content.clone() });
Ok(id)
}
// Anyone updated an element, update it in the database
pub fn set_element(&self, element_id: &ElementId, content: &ElementContent) -> anyhow::Result<()> {
let res = queries::set_element(&self.db, element_id, content);
debug!("Set element with id {:?}: {:?}", element_id, self.get_element(element_id));
self.send_to_peers(MessageContent::SetElement { id: element_id.clone(), content: content.clone() });
res
}
pub fn set_element_content(&self, element_id: &ElementId, content: &ElementContent) -> anyhow::Result<()> {
let res = queries::set_element_content(&self.db, element_id, content);
debug!("Set element content with id {:?}: {:?}", element_id, self.get_element(element_id));
let res = queries::elements::set_content(&self.db, element_id, content);
debug!("Set content of element with id {:?}: {:?}", element_id, self.get_element(element_id));
self.send_to_peers(MessageContent::SetElement { id: element_id.clone(), content: content.clone() });
res
}
pub fn remove_element(&self, element_id: &ElementId) -> anyhow::Result<()> {
let res = queries::remove_element(&self.db, element_id);
let res = queries::elements::remove(&self.db, element_id);
self.send_to_peers(MessageContent::RemoveElement { id: element_id.clone() });
res
}
pub fn get_element(&self, id: &ElementId) -> Option<Element> {
queries::get_element(&self.db, id).ok()
pub fn get_element(&self, id: &ElementId) -> anyhow::Result<Element> {
queries::elements::get(&self.db, id)
}
pub fn get_elements_by_tag(&self, tag: &Tag) -> Vec<ElementId> {
queries::get_elements_by_tag(&self.db, tag)
queries::elements::get_by_tag(&self.db, tag)
.map_err(|e| {error!("{}", e); e})
.unwrap_or(vec![])
}
pub fn set_peer(&self, peer: &Peer) -> anyhow::Result<()> {
queries::add_peer(&self.db, &peer.id(), &peer.name())
queries::peers::put(&self.db, &peer.id(), &peer.name())
}
pub fn get_peers(&self) -> anyhow::Result<Vec<Peer>> {
queries::get_peers(&self.db)
queries::peers::get(&self.db)
}
@ -104,37 +88,3 @@ impl State {
}
}
}
#[cfg(test)]
mod tests {
use crate::state::State;
use crate::state::types::ElementContent;
#[tokio::test]
#[serial_test::serial]
async fn test_create() {
tracing_subscriber::fmt().pretty().init();
let state = State::new().await.unwrap();
let id = state.create_element(&ElementContent::Text("Test-text".to_string())).unwrap();
let el = state.get_element(&id).unwrap();
assert_eq!(
ElementContent::Text("Test-text".to_string()),
el.content().to_owned()
)
}
#[tokio::test]
#[serial_test::serial]
async fn test_update() {
tracing_subscriber::fmt().pretty().init();
let state = State::new().await.unwrap();
let id = state.create_element(&ElementContent::Text("Test-text".to_string())).unwrap();
state.set_element(&id,&ElementContent::Text("Test-text 2".to_string())).unwrap();
let el = state.get_element(&id).unwrap();
assert_eq!(
ElementContent::Text("Test-text 2".to_string()),
el.content().to_owned()
)
}
}