lib

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

decode.rs (3513B)


      1 #![cfg(feature = "serde_json")]
      2 
      3 #[cfg(not(feature = "std"))]
      4 use alloc::{
      5     string::{String, ToString},
      6     vec::Vec,
      7 };
      8 
      9 use radroots_events::{RadrootsNostrEvent, farm::RadrootsFarm, kinds::KIND_FARM, tags::TAG_D};
     10 
     11 use crate::d_tag::validate_d_tag_tag;
     12 use crate::error::EventParseError;
     13 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent};
     14 
     15 const DEFAULT_KIND: u32 = KIND_FARM;
     16 
     17 fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, EventParseError> {
     18     let tag = tags
     19         .iter()
     20         .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_D))
     21         .ok_or(EventParseError::MissingTag(TAG_D))?;
     22     let value = tag
     23         .get(1)
     24         .map(|s| s.to_string())
     25         .ok_or(EventParseError::InvalidTag(TAG_D))?;
     26     if value.trim().is_empty() {
     27         return Err(EventParseError::InvalidTag(TAG_D));
     28     }
     29     validate_d_tag_tag(&value, TAG_D)?;
     30     Ok(value)
     31 }
     32 
     33 pub fn farm_from_event(
     34     kind: u32,
     35     tags: &[Vec<String>],
     36     content: &str,
     37 ) -> Result<RadrootsFarm, EventParseError> {
     38     if kind != DEFAULT_KIND {
     39         return Err(EventParseError::InvalidKind {
     40             expected: "30340",
     41             got: kind,
     42         });
     43     }
     44     if content.trim().is_empty() {
     45         return Err(EventParseError::InvalidJson("content"));
     46     }
     47     let d_tag = parse_d_tag(tags)?;
     48     reject_private_farm_ops_content(content)?;
     49     let mut farm: RadrootsFarm =
     50         serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?;
     51 
     52     if farm.d_tag.trim().is_empty() {
     53         farm.d_tag = d_tag;
     54     } else if farm.d_tag != d_tag {
     55         return Err(EventParseError::InvalidTag(TAG_D));
     56     }
     57 
     58     Ok(farm)
     59 }
     60 
     61 fn reject_private_farm_ops_content(content: &str) -> Result<(), EventParseError> {
     62     let value: serde_json::Value =
     63         serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?;
     64     let Some(object) = value.as_object() else {
     65         return Err(EventParseError::InvalidJson("content"));
     66     };
     67     for key in [
     68         "workspace",
     69         "farm_group_id",
     70         "document_id",
     71         "document_kind",
     72         "crdt_backend",
     73         "encoded_change",
     74         "semantic_kind",
     75         "owner_document_kind",
     76         "owner_document_id",
     77         "relays",
     78         "media_servers",
     79         "supported_kinds",
     80         "protocol_version",
     81     ] {
     82         if object.contains_key(key) {
     83             return Err(EventParseError::InvalidJson("content"));
     84         }
     85     }
     86     Ok(())
     87 }
     88 
     89 pub fn data_from_event(
     90     id: String,
     91     author: String,
     92     published_at: u32,
     93     kind: u32,
     94     content: String,
     95     tags: Vec<Vec<String>>,
     96 ) -> Result<RadrootsParsedData<RadrootsFarm>, EventParseError> {
     97     let farm = farm_from_event(kind, &tags, &content)?;
     98     Ok(RadrootsParsedData::new(
     99         id,
    100         author,
    101         published_at,
    102         kind,
    103         farm,
    104     ))
    105 }
    106 
    107 pub fn parsed_from_event(
    108     id: String,
    109     author: String,
    110     published_at: u32,
    111     kind: u32,
    112     content: String,
    113     tags: Vec<Vec<String>>,
    114     sig: String,
    115 ) -> Result<RadrootsParsedEvent<RadrootsFarm>, EventParseError> {
    116     let data = data_from_event(
    117         id.clone(),
    118         author.clone(),
    119         published_at,
    120         kind,
    121         content.clone(),
    122         tags.clone(),
    123     )?;
    124     Ok(RadrootsParsedEvent {
    125         event: RadrootsNostrEvent {
    126             id,
    127             author,
    128             created_at: published_at,
    129             kind,
    130             content,
    131             tags,
    132             sig,
    133         },
    134         data,
    135     })
    136 }