use sapio_base::serialization_helpers::SArc;
use sapio_base::simp::{SIMPAttachableAt, SIMPError, SIMP};
use sapio_base::{effects::EffectPath, simp::ContinuationPointLT};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::{collections::BTreeMap, sync::Arc};
#[derive(Serialize, Deserialize, JsonSchema, Clone, Debug, PartialEq, Eq)]
pub struct ContinuationPoint {
pub schema: Option<SArc<Value>>,
#[serde(serialize_with = "sapio_base::serialization_helpers::serializer")]
#[serde(deserialize_with = "sapio_base::serialization_helpers::deserializer")]
pub path: Arc<EffectPath>,
pub simp: BTreeMap<i64, Value>,
}
impl ContinuationPoint {
pub fn at(schema: Option<Arc<Value>>, path: Arc<EffectPath>) -> Self {
ContinuationPoint {
schema: schema.map(SArc),
path,
simp: Default::default(),
}
}
pub fn add_simp(
mut self,
s: &dyn SIMPAttachableAt<ContinuationPointLT>,
) -> Result<Self, SIMPError> {
let old = self.simp.insert(s.get_protocol_number(), s.to_json()?);
if let Some(old) = old {
Err(SIMPError::AlreadyDefined(old))
} else {
Ok(self)
}
}
}
#[cfg(test)]
mod test {
use super::*;
use sapio_base::effects::PathFragment;
#[test]
fn test_continuation_point_ser() -> Result<(), Box<dyn std::error::Error>> {
let a: ContinuationPoint = ContinuationPoint::at(
Some(Arc::new(
serde_json::to_value(&schemars::schema_for!(ContinuationPoint)).unwrap(),
)),
EffectPath::push(None, PathFragment::Named(SArc(Arc::new("one".into())))),
);
let b: ContinuationPoint = serde_json::from_str(&format!(
"{{\"schema\":{},\"path\":\"one\",\"simp\":{{}}}}",
serde_json::to_string(&schemars::schema_for!(ContinuationPoint))?
))?;
assert_eq!(a, b);
Ok(())
}
}