use std::collections::BTreeMap;
use crate::{ProtocolError, ValidationError};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Documentation {
pub summary: String,
pub details: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Object {
pub name: String,
pub description: Option<String>,
pub interfaces: Vec<String>,
pub r#ref: Option<String>,
pub validator: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterfaceDescriptor {
pub format: String,
pub documentation: Option<Documentation>,
pub types: Vec<TypeDeclaration>,
pub operations: Vec<OperationDeclaration>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeDeclaration {
pub name: String,
pub documentation: Option<Documentation>,
pub definition: TypeExpr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TypeExpr {
Unit,
Boolean,
Integer,
Number,
String,
Bytes,
Json,
Entry,
Named {
name: String,
},
Record {
fields: Vec<FieldDeclaration>,
},
List {
items: Box<TypeExpr>,
},
Enum {
cases: Vec<EnumCase>,
},
Union {
cases: Vec<UnionCase>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FieldDeclaration {
pub name: String,
pub required: bool,
pub documentation: Option<Documentation>,
pub r#type: TypeExpr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumCase {
pub name: String,
pub documentation: Option<Documentation>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UnionCase {
pub name: String,
pub documentation: Option<Documentation>,
pub payload: Option<TypeExpr>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OperationDeclaration {
pub name: String,
pub documentation: Option<Documentation>,
pub parameters: Vec<ParameterDeclaration>,
pub returns: ReturnDeclaration,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParameterDeclaration {
pub name: String,
pub required: bool,
pub documentation: Option<Documentation>,
pub r#type: TypeExpr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ReturnDeclaration {
pub documentation: Option<Documentation>,
pub r#type: TypeExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Unit,
Boolean(bool),
Integer(i64),
Number(f64),
String(String),
Bytes(Vec<u8>),
Record(BTreeMap<String, Value>),
List(Vec<Value>),
}
impl Value {
#[must_use]
pub fn kind(&self) -> crate::ValueKind {
match self {
Self::Unit => crate::ValueKind::Unit,
Self::Boolean(_) => crate::ValueKind::Boolean,
Self::Integer(_) => crate::ValueKind::Integer,
Self::Number(_) => crate::ValueKind::Number,
Self::String(_) => crate::ValueKind::String,
Self::Bytes(_) => crate::ValueKind::Bytes,
Self::Record(_) => crate::ValueKind::Record,
Self::List(_) => crate::ValueKind::List,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ObserveRequest {
pub path: String,
pub depth: u32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ObjectObservation {
pub object: Object,
pub children: Option<Vec<ObjectObservation>>,
}
pub type ObserveResponse = ObjectObservation;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FetchInterfaceRequest {
pub interface: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FetchInterfaceResponse {
pub interface: String,
pub descriptor: InterfaceDescriptor,
pub validator: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Target {
pub path: String,
pub validator: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterfaceTarget {
pub reference: String,
pub validator: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CallOperationRequest {
pub target: Target,
pub interface: InterfaceTarget,
pub operation: String,
pub arguments: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CallOperationResponse {
pub result: Value,
pub validator: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProtocolResult<T> {
Success(T),
Failure(ProtocolError),
}
impl Object {
pub fn validate(&self) -> Result<(), ValidationError> {
crate::validation::validate_object(self)
}
pub fn validate_at_path(&self, path: &str) -> Result<(), ValidationError> {
crate::validation::validate_object_at_path(self, path)
}
pub fn validate_consistency_with(&self, other: &Self) -> Result<(), ValidationError> {
crate::validation::validate_object_consistency(self, other)
}
}
impl InterfaceDescriptor {
pub fn validate(&self) -> Result<(), ValidationError> {
crate::validation::validate_descriptor(self)
}
pub fn validate_value(&self, r#type: &TypeExpr, value: &Value) -> Result<(), ValidationError> {
crate::validation::validate_root_value(self, r#type, value)
}
pub fn validate_arguments(
&self,
operation: &str,
arguments: &BTreeMap<String, Value>,
) -> Result<(), ValidationError> {
crate::validation::validate_arguments(self, operation, arguments)
}
pub fn validate_result(&self, operation: &str, result: &Value) -> Result<(), ValidationError> {
crate::validation::validate_result(self, operation, result)
}
pub fn validate_call(&self, request: &CallOperationRequest) -> Result<(), ValidationError> {
crate::validation::validate_call(self, request)
}
}
impl ObserveRequest {
pub fn validate(&self) -> Result<(), ValidationError> {
crate::validation::validate_path(&self.path)
}
pub fn validate_response(&self, response: &ObserveResponse) -> Result<(), ValidationError> {
crate::validation::validate_observe_response(response, self)
}
}
impl FetchInterfaceResponse {
pub fn validate_for(&self, request: &FetchInterfaceRequest) -> Result<(), ValidationError> {
crate::validation::validate_fetch_interface_response(self, request)
}
}
impl CallOperationRequest {
pub fn validate_with(&self, descriptor: &InterfaceDescriptor) -> Result<(), ValidationError> {
descriptor.validate_call(self)
}
}
impl CallOperationResponse {
pub fn validate_for(
&self,
descriptor: &InterfaceDescriptor,
operation: &str,
) -> Result<(), ValidationError> {
descriptor.validate_result(operation, &self.result)
}
}