shrike 0.1.1

AT Protocol library for Rust
Documentation
// Code generated by lexgen. DO NOT EDIT.

/// NSID for the GraphVerification record.
pub const NSID_GRAPH_VERIFICATION: &str = "app.bsky.graph.verification";

/// GraphVerification — Record declaring a verification relationship between two accounts. Verifications are only considered valid by an app if issued by an account the app considers trusted.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GraphVerification {
    /// Date of when the verification was created.
    pub created_at: crate::syntax::Datetime,
    /// Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying.
    pub display_name: String,
    /// Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.
    pub handle: crate::syntax::Handle,
    /// DID of the subject the verification applies to.
    pub subject: crate::syntax::Did,
    /// Extra fields not defined in the schema (JSON).
    #[serde(flatten)]
    pub extra: std::collections::HashMap<String, serde_json::Value>,
    /// Extra fields not defined in the schema (CBOR).
    #[serde(skip)]
    pub extra_cbor: Vec<(String, Vec<u8>)>,
}

impl GraphVerification {
    pub fn to_cbor(&self) -> Result<Vec<u8>, crate::cbor::CborError> {
        let mut buf = Vec::new();
        self.encode_cbor(&mut buf)?;
        Ok(buf)
    }

    pub fn encode_cbor(&self, buf: &mut Vec<u8>) -> Result<(), crate::cbor::CborError> {
        if self.extra_cbor.is_empty() {
            // Fast path: no extra fields to merge.
            let count = 4u64;
            crate::cbor::Encoder::new(&mut *buf).encode_map_header(count)?;
            crate::cbor::Encoder::new(&mut *buf).encode_text("handle")?;
            crate::cbor::Encoder::new(&mut *buf).encode_text(self.handle.as_str())?;
            crate::cbor::Encoder::new(&mut *buf).encode_text("subject")?;
            crate::cbor::Encoder::new(&mut *buf).encode_text(self.subject.as_str())?;
            crate::cbor::Encoder::new(&mut *buf).encode_text("createdAt")?;
            crate::cbor::Encoder::new(&mut *buf).encode_text(self.created_at.as_str())?;
            crate::cbor::Encoder::new(&mut *buf).encode_text("displayName")?;
            crate::cbor::Encoder::new(&mut *buf).encode_text(&self.display_name)?;
        } else {
            // Slow path: merge known fields with extra_cbor, sort, encode.
            let mut pairs: Vec<(&str, Vec<u8>)> = Vec::new();
            {
                let mut vbuf = Vec::new();
                crate::cbor::Encoder::new(&mut vbuf).encode_text(self.handle.as_str())?;
                pairs.push(("handle", vbuf));
            }
            {
                let mut vbuf = Vec::new();
                crate::cbor::Encoder::new(&mut vbuf).encode_text(self.subject.as_str())?;
                pairs.push(("subject", vbuf));
            }
            {
                let mut vbuf = Vec::new();
                crate::cbor::Encoder::new(&mut vbuf).encode_text(self.created_at.as_str())?;
                pairs.push(("createdAt", vbuf));
            }
            {
                let mut vbuf = Vec::new();
                crate::cbor::Encoder::new(&mut vbuf).encode_text(&self.display_name)?;
                pairs.push(("displayName", vbuf));
            }
            for (k, v) in &self.extra_cbor {
                pairs.push((k.as_str(), v.clone()));
            }
            pairs.sort_by(|a, b| crate::cbor::cbor_key_cmp(a.0, b.0));
            crate::cbor::Encoder::new(&mut *buf).encode_map_header(pairs.len() as u64)?;
            for (k, v) in &pairs {
                crate::cbor::Encoder::new(&mut *buf).encode_text(k)?;
                buf.extend_from_slice(v);
            }
        }
        Ok(())
    }

    pub fn from_cbor(data: &[u8]) -> Result<Self, crate::cbor::CborError> {
        let mut decoder = crate::cbor::Decoder::new(data);
        let result = Self::decode_cbor(&mut decoder)?;
        if !decoder.is_empty() {
            return Err(crate::cbor::CborError::InvalidCbor("trailing data".into()));
        }
        Ok(result)
    }

    pub fn decode_cbor(decoder: &mut crate::cbor::Decoder) -> Result<Self, crate::cbor::CborError> {
        let val = decoder.decode()?;
        let entries = match val {
            crate::cbor::Value::Map(entries) => entries,
            _ => return Err(crate::cbor::CborError::InvalidCbor("expected map".into())),
        };

        let mut field_handle: Option<crate::syntax::Handle> = None;
        let mut field_subject: Option<crate::syntax::Did> = None;
        let mut field_created_at: Option<crate::syntax::Datetime> = None;
        let mut field_display_name: Option<String> = None;
        let mut extra_cbor: Vec<(String, Vec<u8>)> = Vec::new();

        for (key, value) in entries {
            match key {
                "handle" => {
                    if let crate::cbor::Value::Text(s) = value {
                        field_handle = Some(
                            crate::syntax::Handle::try_from(s)
                                .map_err(|e| crate::cbor::CborError::InvalidCbor(e.to_string()))?,
                        );
                    } else {
                        return Err(crate::cbor::CborError::InvalidCbor("expected text".into()));
                    }
                }
                "subject" => {
                    if let crate::cbor::Value::Text(s) = value {
                        field_subject = Some(
                            crate::syntax::Did::try_from(s)
                                .map_err(|e| crate::cbor::CborError::InvalidCbor(e.to_string()))?,
                        );
                    } else {
                        return Err(crate::cbor::CborError::InvalidCbor("expected text".into()));
                    }
                }
                "createdAt" => {
                    if let crate::cbor::Value::Text(s) = value {
                        field_created_at = Some(
                            crate::syntax::Datetime::try_from(s)
                                .map_err(|e| crate::cbor::CborError::InvalidCbor(e.to_string()))?,
                        );
                    } else {
                        return Err(crate::cbor::CborError::InvalidCbor("expected text".into()));
                    }
                }
                "displayName" => {
                    if let crate::cbor::Value::Text(s) = value {
                        field_display_name = Some(s.to_string());
                    } else {
                        return Err(crate::cbor::CborError::InvalidCbor("expected text".into()));
                    }
                }
                _ => {
                    let raw = crate::cbor::encode_value(&value)?;
                    extra_cbor.push((key.to_string(), raw));
                }
            }
        }

        Ok(GraphVerification {
            handle: field_handle.ok_or_else(|| {
                crate::cbor::CborError::InvalidCbor("missing required field 'handle'".into())
            })?,
            subject: field_subject.ok_or_else(|| {
                crate::cbor::CborError::InvalidCbor("missing required field 'subject'".into())
            })?,
            created_at: field_created_at.ok_or_else(|| {
                crate::cbor::CborError::InvalidCbor("missing required field 'createdAt'".into())
            })?,
            display_name: field_display_name.ok_or_else(|| {
                crate::cbor::CborError::InvalidCbor("missing required field 'displayName'".into())
            })?,
            extra: std::collections::HashMap::new(),
            extra_cbor,
        })
    }
}