use std::error::Error;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::maps::{ComponentMap, FieldMap, TypeMap};
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[must_use]
pub struct ComponentSignature {
#[serde(default)]
pub name: String,
#[serde(default)]
pub inputs: FieldMap,
#[serde(default)]
pub outputs: FieldMap,
}
impl ComponentSignature {
pub fn new<T: AsRef<str>>(name: T) -> Self {
Self {
name: name.as_ref().to_owned(),
..Default::default()
}
}
pub fn add_input(mut self, name: impl AsRef<str>, input_type: TypeSignature) -> Self {
self.inputs.insert(name, input_type);
self
}
pub fn add_output(mut self, name: impl AsRef<str>, input_type: TypeSignature) -> Self {
self.outputs.insert(name, input_type);
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, serde_repr::Deserialize_repr, serde_repr::Serialize_repr)]
#[must_use]
#[repr(u32)]
pub enum CollectionVersion {
V0 = 0,
}
impl Default for CollectionVersion {
fn default() -> Self {
Self::V0
}
}
impl From<CollectionVersion> for u32 {
fn from(v: CollectionVersion) -> Self {
match v {
CollectionVersion::V0 => 0,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Copy)]
#[must_use]
pub struct CollectionFeatures {
pub streaming: bool,
pub stateful: bool,
pub version: CollectionVersion,
}
impl CollectionFeatures {
pub fn v0(stateful: bool, streaming: bool) -> Self {
Self {
streaming,
stateful,
version: CollectionVersion::V0,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[must_use]
pub struct CollectionSignature {
pub name: Option<String>,
pub features: CollectionFeatures,
pub format: u32,
pub version: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub wellknown: Vec<WellKnownSchema>,
#[serde(default, skip_serializing_if = "TypeMap::is_empty")]
pub types: TypeMap,
pub components: ComponentMap,
#[serde(default, skip_serializing_if = "TypeMap::is_empty")]
pub config: TypeMap,
}
impl CollectionSignature {
pub fn new<T: AsRef<str>>(name: T) -> Self {
Self {
name: Some(name.as_ref().to_owned()),
..Default::default()
}
}
#[must_use]
pub fn get_component(&self, field: &str) -> Option<&ComponentSignature> {
self.components.get(field)
}
pub fn add_component(mut self, signature: ComponentSignature) -> Self {
self.components.insert(signature.name.clone(), signature);
self
}
pub fn version(mut self, version: impl AsRef<str>) -> Self {
self.version = version.as_ref().to_owned();
self
}
pub fn format(mut self, format: u32) -> Self {
self.format = format;
self
}
pub fn features(mut self, features: CollectionFeatures) -> Self {
self.features = features;
self
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct WellKnownSchema {
pub capabilities: Vec<String>,
pub url: String,
pub schema: CollectionSignature,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[must_use]
#[serde(tag = "type")]
pub enum TypeDefinition {
#[serde(rename = "struct")]
Struct(StructSignature),
#[serde(rename = "enum")]
Enum(EnumSignature),
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[must_use]
pub struct EnumSignature {
pub name: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub values: Vec<EnumVariant>,
}
impl EnumSignature {
pub fn new<T: AsRef<str>>(name: T, values: Vec<EnumVariant>) -> Self {
Self {
name: name.as_ref().to_owned(),
values,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[must_use]
pub struct EnumVariant {
pub name: String,
pub index: u32,
}
impl EnumVariant {
pub fn new<T: AsRef<str>>(name: T, index: u32) -> Self {
Self {
name: name.as_ref().to_owned(),
index,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[must_use]
pub struct StructSignature {
pub name: String,
pub fields: FieldMap,
}
impl StructSignature {
pub fn new<T: AsRef<str>>(name: T, fields: FieldMap) -> Self {
Self {
name: name.as_ref().to_owned(),
fields,
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[must_use]
pub enum HostedType {
Collection(CollectionSignature),
}
impl HostedType {
#[must_use]
pub fn get_name(&self) -> &Option<String> {
match self {
HostedType::Collection(s) => &s.name,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
#[must_use]
pub enum TypeSignature {
I8,
I16,
I32,
I64,
U8,
U16,
U32,
U64,
F32,
F64,
Bool,
String,
Datetime,
Bytes,
Value,
Internal(InternalType),
Ref {
#[serde(rename = "ref")]
reference: String,
},
List {
element: Box<TypeSignature>,
},
Optional {
option: Box<TypeSignature>,
},
Map {
key: Box<TypeSignature>,
value: Box<TypeSignature>,
},
Link {
#[serde(default)]
schemas: Vec<String>,
},
Struct,
}
#[derive(Debug)]
pub struct ParseError(String);
impl Error for ParseError {}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Could not parse {} into a TypeSignature.", self.0)
}
}
impl FromStr for TypeSignature {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let t = match s {
"i8" => Self::I8,
"i16" => Self::I16,
"i32" => Self::I32,
"i64" => Self::I64,
"u8" => Self::U8,
"u16" => Self::U16,
"u32" => Self::U32,
"u64" => Self::U64,
"f32" => Self::F32,
"f64" => Self::F64,
"bool" => Self::Bool,
"bytes" => Self::Bytes,
"value" => Self::Value,
"string" => Self::String,
"datetime" => Self::Datetime,
_ => return Err(ParseError(s.to_owned())),
};
Ok(t)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
#[serde(tag = "id")]
pub enum InternalType {
#[serde(rename = "__input__")]
ComponentInput,
}
impl FromStr for InternalType {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let t = match s {
"component_input" => Self::ComponentInput,
_ => return Err(ParseError(s.to_owned())),
};
Ok(t)
}
}