lib

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

decode.rs (4522B)


      1 #![cfg(feature = "json")]
      2 
      3 #[cfg(not(feature = "std"))]
      4 use alloc::{
      5     string::{String, ToString},
      6     vec::Vec,
      7 };
      8 
      9 use radroots_event::{
     10     envelope::kind::{KIND_FARM, KIND_PLOT},
     11     farm::FarmRef,
     12     farm::plot::Plot,
     13     tag::name::TAG_D,
     14 };
     15 
     16 use crate::d_tag::validate_d_tag_tag;
     17 use crate::error::EventParseError;
     18 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent};
     19 
     20 const TAG_A: &str = "a";
     21 const TAG_P: &str = "p";
     22 const DEFAULT_KIND: u32 = KIND_PLOT;
     23 
     24 fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, EventParseError> {
     25     let tag = tags
     26         .iter()
     27         .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_D))
     28         .ok_or(EventParseError::MissingTag(TAG_D))?;
     29     let value = tag
     30         .get(1)
     31         .map(|s| s.to_string())
     32         .ok_or(EventParseError::InvalidTag(TAG_D))?;
     33     if value.trim().is_empty() {
     34         return Err(EventParseError::InvalidTag(TAG_D));
     35     }
     36     validate_d_tag_tag(&value, TAG_D)?;
     37     Ok(value)
     38 }
     39 
     40 fn parse_farm_ref(tags: &[Vec<String>]) -> Result<FarmRef, EventParseError> {
     41     let tag = tags
     42         .iter()
     43         .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_A))
     44         .ok_or(EventParseError::MissingTag(TAG_A))?;
     45     let value = tag
     46         .get(1)
     47         .map(|s| s.to_string())
     48         .ok_or(EventParseError::InvalidTag(TAG_A))?;
     49     let mut parts = value.splitn(3, ':');
     50     let kind = parts
     51         .next()
     52         .and_then(|v| v.parse::<u32>().ok())
     53         .ok_or(EventParseError::InvalidTag(TAG_A))?;
     54     if kind != KIND_FARM {
     55         return Err(EventParseError::InvalidTag(TAG_A));
     56     }
     57     let pubkey = parts
     58         .next()
     59         .ok_or(EventParseError::InvalidTag(TAG_A))?
     60         .to_string();
     61     let d_tag = parts
     62         .next()
     63         .ok_or(EventParseError::InvalidTag(TAG_A))?
     64         .to_string();
     65     if pubkey.trim().is_empty() || d_tag.trim().is_empty() {
     66         return Err(EventParseError::InvalidTag(TAG_A));
     67     }
     68     validate_d_tag_tag(&d_tag, TAG_A)?;
     69     Ok(FarmRef { pubkey, d_tag })
     70 }
     71 
     72 fn parse_farm_pubkey(tags: &[Vec<String>]) -> Result<String, EventParseError> {
     73     let tag = tags
     74         .iter()
     75         .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_P))
     76         .ok_or(EventParseError::MissingTag(TAG_P))?;
     77     let value = tag
     78         .get(1)
     79         .map(|s| s.to_string())
     80         .ok_or(EventParseError::InvalidTag(TAG_P))?;
     81     if value.trim().is_empty() {
     82         return Err(EventParseError::InvalidTag(TAG_P));
     83     }
     84     Ok(value)
     85 }
     86 
     87 pub fn plot_from_event(
     88     kind: u32,
     89     tags: &[Vec<String>],
     90     content: &str,
     91 ) -> Result<Plot, EventParseError> {
     92     if kind != DEFAULT_KIND {
     93         return Err(EventParseError::InvalidKind {
     94             expected: "30350",
     95             got: kind,
     96         });
     97     }
     98     if content.trim().is_empty() {
     99         return Err(EventParseError::InvalidJson("content"));
    100     }
    101     let d_tag = parse_d_tag(tags)?;
    102     let farm_ref = parse_farm_ref(tags)?;
    103     let farm_pubkey = parse_farm_pubkey(tags)?;
    104     let mut plot: Plot =
    105         serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?;
    106 
    107     if plot.d_tag.trim().is_empty() {
    108         plot.d_tag = d_tag;
    109     } else if plot.d_tag != d_tag {
    110         return Err(EventParseError::InvalidTag(TAG_D));
    111     }
    112 
    113     if plot.farm.pubkey.trim().is_empty() || plot.farm.d_tag.trim().is_empty() {
    114         plot.farm = farm_ref;
    115     } else if plot.farm.pubkey != farm_ref.pubkey || plot.farm.d_tag != farm_ref.d_tag {
    116         return Err(EventParseError::InvalidTag(TAG_A));
    117     }
    118     if plot.farm.pubkey != farm_pubkey {
    119         return Err(EventParseError::InvalidTag(TAG_P));
    120     }
    121 
    122     Ok(plot)
    123 }
    124 
    125 pub fn data_from_event(
    126     id: String,
    127     author: String,
    128     published_at: u64,
    129     kind: u32,
    130     content: String,
    131     tags: Vec<Vec<String>>,
    132 ) -> Result<RadrootsParsedData<Plot>, EventParseError> {
    133     let plot = plot_from_event(kind, &tags, &content)?;
    134     Ok(RadrootsParsedData::new(
    135         id,
    136         author,
    137         published_at,
    138         kind,
    139         plot,
    140     ))
    141 }
    142 
    143 pub fn parsed_from_event(
    144     id: String,
    145     author: String,
    146     published_at: u64,
    147     kind: u32,
    148     content: String,
    149     tags: Vec<Vec<String>>,
    150     sig: String,
    151 ) -> Result<RadrootsParsedEvent<Plot>, EventParseError> {
    152     let data = data_from_event(
    153         id.clone(),
    154         author.clone(),
    155         published_at,
    156         kind,
    157         content.clone(),
    158         tags.clone(),
    159     )?;
    160     RadrootsParsedEvent::from_event_parts(id, author, published_at, kind, content, tags, sig, data)
    161 }