Skip to main content
Glama
vector_clock_id.rs4 kB
pub use si_id::{ VectorClockActorId, VectorClockChangeSetId, }; use crate::ulid::Ulid; #[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)] pub struct VectorClockId { change_set_id: VectorClockChangeSetId, actor_id: VectorClockActorId, } pub struct VectorClockIdStringDeserializeVisitor; impl serde::de::Visitor<'_> for VectorClockIdStringDeserializeVisitor { type Value = VectorClockId; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a string reprensenting a VectorClockId") } fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error, { let (change_set_id_string, actor_id_string) = v.split_once(';').ok_or(E::custom( format!("{v} is not a valid VectorClockId string representation."), ))?; let change_set_id = Ulid::from_string(change_set_id_string).map_err(|e| { E::custom(format!( "VectorClock ChangeSetId \"{change_set_id_string}\" is not a valid Ulid representation: {e}" )) })?; let actor_id = Ulid::from_string(actor_id_string).map_err(|e| { E::custom(format!( "VectorClock ActorId \"{actor_id_string}\" is not a valid Ulid representation: {e}" )) })?; Ok(VectorClockId::new(change_set_id, actor_id)) } } impl<'de> serde::Deserialize<'de> for VectorClockId { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>, { deserializer.deserialize_str(VectorClockIdStringDeserializeVisitor) } } impl serde::Serialize for VectorClockId { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { let string_vector_clock_id = format!("{};{}", self.change_set_id, self.actor_id); serializer.serialize_str(&string_vector_clock_id) } } impl std::fmt::Display for VectorClockId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "(ChangeSet({}), Actor({}))", self.change_set_id, self.actor_id ) } } impl VectorClockId { pub fn new( change_set_id: impl Into<VectorClockChangeSetId>, actor_id: impl Into<VectorClockActorId>, ) -> Self { Self { change_set_id: change_set_id.into(), actor_id: actor_id.into(), } } pub fn change_set_id(&self) -> VectorClockChangeSetId { self.change_set_id } pub fn actor_id(&self) -> VectorClockActorId { self.actor_id } } #[cfg(test)] mod tests { use std::collections::HashMap; use super::*; #[test] fn display() { let cs_text = "01D39ZY06FGSCTVN4T2V9PKHFZ"; let actor_text = "00000000000000000000000000"; let change_set_ulid = Ulid::from_string(cs_text).expect("make ulid from string"); let actor_ulid = Ulid::from_string(actor_text).expect("make actor from string"); let vector_clock_id = VectorClockId::new( VectorClockChangeSetId::from(change_set_ulid), VectorClockActorId::from(actor_ulid), ); let expected = format!("(ChangeSet({cs_text}), Actor({actor_text}))"); let display = format!("{vector_clock_id}"); assert_eq!(expected, display); } #[test] fn serde_json() { let mut vector_clock_map = HashMap::new(); for i in 0..10 { let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); vector_clock_map.insert(vector_clock_id, i); } let json_string = serde_json::to_string(&vector_clock_map).expect("should serialize to string"); let deserialized: HashMap<VectorClockId, i32> = serde_json::from_str(&json_string).expect("should deserialize"); assert_eq!(vector_clock_map, deserialized); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server