From 2b5caa2b306dc6a8c873f9ae3a2e0830cfbe5765 Mon Sep 17 00:00:00 2001 From: Jakub Stachurski Date: Sat, 19 Sep 2026 23:43:04 +0200 Subject: Add parsing of a JMAP request Also adds: - MethodRegistry to Capability and CapabilityRegistry - Better parsing for JMAPId - Eq and PartialEq for dates - Tests for JMAPRequest - Core/Echo method - Support for Invocations --- src/types.rs | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'src/types.rs') diff --git a/src/types.rs b/src/types.rs index 0060e71..d2713da 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,16 +1,17 @@ use jiff::Timestamp; use jiff::civil::DateTime; -use serde::de::{DeserializeOwned, Error}; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serde_json::{Number, Value}; -use std::any::Any; use std::collections::BTreeMap; -use std::collections::btree_map::{Iter, Keys}; use std::hash::Hash; +use std::str::FromStr; + +use crate::request::JMAPError; // Types // *, unknown value -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(untagged)] pub enum JUnknown { Object(BTreeMap), @@ -152,6 +153,36 @@ where /// TODO: Add the restrictions above #[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, PartialOrd, Ord, Debug)] pub struct JMAPId(pub String); + +impl FromStr for JMAPId { + type Err = JMAPError; + fn from_str(s: &str) -> Result { + if s.len() > 255 || s.len() < 1 { + return Err(JMAPError::ParseError("Invalid ID size".to_string())); + } + + let mut out = String::with_capacity(s.len()); + for c in s.chars() { + if !(c.is_ascii_alphanumeric() || c == '-' || c == '_') { + return Err(JMAPError::ParseError(format!( + "ID {} contains invalid character {}", + s, c + ))); + } + + out.push(c); + } + + Ok(Self(out)) + } +} + +impl AsRef for JMAPId { + fn as_ref(&self) -> &str { + return &self.0; + } +} + //}}} // 1.3 Int and UnsignedInt {{{ pub type JInt = i64; @@ -164,7 +195,7 @@ pub type JUint = u64; /// TODO: To ensure a normalized form, the time-setfrac MUST always be ommitted if zero, and any /// letters in the string (eg. "T" and "Z") must be uppercase. -#[derive(Deserialize, Serialize, Clone, Debug)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, PartialOrd)] pub struct JDate(DateTime); impl JDate { /// Convert from a JUTCDate type to system time @@ -193,7 +224,7 @@ impl JDate { } /// Where UTCDate is given as a type, it means a Date where the time-offset component MUST be Z (i.e., it must be in UTC time). For example, 2014-10-30T06:12:00Z -#[derive(Deserialize, Serialize, Clone, Debug)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, PartialOrd)] pub struct JUTCDate(Timestamp); impl JUTCDate { /// Convert from a JDate type -- cgit v1.3.1