lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

encode.rs (4271B)


      1 #[cfg(not(feature = "std"))]
      2 use alloc::{
      3     string::{String, ToString},
      4     vec::Vec,
      5 };
      6 
      7 #[cfg(feature = "serde_json")]
      8 use radroots_events::farm_crdt::KIND_FARM_CRDT_CHANGE;
      9 use radroots_events::{
     10     farm_crdt::{RADROOTS_FARM_CRDT_CHANGE_SCHEMA, RADROOTS_FARM_CRDT_TAG, RadrootsFarmCrdtChange},
     11     farm_workspace::KIND_FARM_WORKSPACE_MANIFEST,
     12     tags::{TAG_A, TAG_D, TAG_H, TAG_P, TAG_T},
     13 };
     14 
     15 use crate::d_tag::validate_d_tag;
     16 use crate::error::EventEncodeError;
     17 use crate::field_helpers::{
     18     address_string, push_optional_tag, push_tag, validate_non_empty_base64url,
     19     validate_non_empty_field,
     20 };
     21 #[cfg(feature = "serde_json")]
     22 use crate::wire::WireEventParts;
     23 
     24 pub fn farm_crdt_change_build_tags(
     25     change: &RadrootsFarmCrdtChange,
     26 ) -> Result<Vec<Vec<String>>, EventEncodeError> {
     27     farm_crdt_change_build_tags_with_author(change, None)
     28 }
     29 
     30 pub fn farm_crdt_change_build_tags_with_author(
     31     change: &RadrootsFarmCrdtChange,
     32     author_pubkey: Option<&str>,
     33 ) -> Result<Vec<Vec<String>>, EventEncodeError> {
     34     validate_change(change)?;
     35     if let Some(author_pubkey) = author_pubkey {
     36         validate_non_empty_field(author_pubkey, "author_pubkey")?;
     37     }
     38     let workspace = address_string(
     39         KIND_FARM_WORKSPACE_MANIFEST,
     40         &change.workspace.pubkey,
     41         &change.workspace.d_tag,
     42         "workspace",
     43     )?;
     44     let mut tags = Vec::new();
     45     push_tag(&mut tags, TAG_H, change.farm_group_id.as_str());
     46     push_tag(&mut tags, TAG_D, change.document_id.as_str());
     47     push_tag(&mut tags, TAG_A, workspace);
     48     push_optional_tag(&mut tags, TAG_P, author_pubkey);
     49     push_tag(&mut tags, TAG_T, RADROOTS_FARM_CRDT_TAG);
     50     Ok(tags)
     51 }
     52 
     53 #[cfg(feature = "serde_json")]
     54 pub fn to_wire_parts(change: &RadrootsFarmCrdtChange) -> Result<WireEventParts, EventEncodeError> {
     55     to_wire_parts_with_kind(change, KIND_FARM_CRDT_CHANGE)
     56 }
     57 
     58 #[cfg(feature = "serde_json")]
     59 pub fn to_wire_parts_with_author(
     60     change: &RadrootsFarmCrdtChange,
     61     author_pubkey: &str,
     62 ) -> Result<WireEventParts, EventEncodeError> {
     63     to_wire_parts_with_kind_and_author(change, KIND_FARM_CRDT_CHANGE, Some(author_pubkey))
     64 }
     65 
     66 #[cfg(feature = "serde_json")]
     67 pub fn to_wire_parts_with_kind(
     68     change: &RadrootsFarmCrdtChange,
     69     kind: u32,
     70 ) -> Result<WireEventParts, EventEncodeError> {
     71     to_wire_parts_with_kind_and_author(change, kind, None)
     72 }
     73 
     74 #[cfg(feature = "serde_json")]
     75 pub fn to_wire_parts_with_kind_and_author(
     76     change: &RadrootsFarmCrdtChange,
     77     kind: u32,
     78     author_pubkey: Option<&str>,
     79 ) -> Result<WireEventParts, EventEncodeError> {
     80     if kind != KIND_FARM_CRDT_CHANGE {
     81         return Err(EventEncodeError::InvalidKind(kind));
     82     }
     83     let tags = farm_crdt_change_build_tags_with_author(change, author_pubkey)?;
     84     let content = serde_json::to_string(change).map_err(|_| EventEncodeError::Json)?;
     85     Ok(WireEventParts {
     86         kind,
     87         content,
     88         tags,
     89     })
     90 }
     91 
     92 pub(crate) fn validate_change(change: &RadrootsFarmCrdtChange) -> Result<(), EventEncodeError> {
     93     if change.schema != RADROOTS_FARM_CRDT_CHANGE_SCHEMA {
     94         return Err(EventEncodeError::InvalidField("schema"));
     95     }
     96     validate_non_empty_field(&change.farm_group_id, "farm_group_id")?;
     97     validate_d_tag(&change.document_id, "document_id")?;
     98     validate_non_empty_field(&change.workspace.pubkey, "workspace.pubkey")?;
     99     validate_d_tag(&change.workspace.d_tag, "workspace.d_tag")?;
    100     validate_non_empty_field(&change.actor_id, "actor_id")?;
    101     validate_non_empty_field(&change.change_hash, "change_hash")?;
    102     for dependency in &change.dependencies {
    103         validate_non_empty_field(dependency, "dependencies")?;
    104     }
    105     validate_non_empty_base64url(&change.encoded_change, "encoded_change")?;
    106     if change.business_time_ms == 0 {
    107         return Err(EventEncodeError::InvalidField("business_time_ms"));
    108     }
    109     if let Some(version) = change.crdt_backend_version.as_deref() {
    110         validate_non_empty_field(version, "crdt_backend_version")?;
    111     }
    112     if let Some(member_id) = change.author_member_id.as_deref() {
    113         validate_non_empty_field(member_id, "author_member_id")?;
    114     }
    115     if let Some(app_version) = change.app_version.as_deref() {
    116         validate_non_empty_field(app_version, "app_version")?;
    117     }
    118     Ok(())
    119 }