1pub mod declaration;
13pub mod graph;
14pub mod identity;
15mod payload;
16
17pub use declaration::{Field, Kind};
20pub use payload::{Event, PathElement, PayloadError, Scalar, Validator, VisitError};
21
22use std::borrow::Cow;
26use serde::{Deserialize, Serialize};
28pub const MAX_DEPTH: usize = 32;
33pub const MAX_NAME_BYTES: usize = 256;
34
35macro_rules! wrapper {
39 ($($ty:ty => $kind:ident),* $(,)?) => {$(
40 impl Described for $ty {
41 const FIELD_KIND: graph::Kind<declaration::Definition> = graph::Kind::$kind;
42 const NAME: &'static str = concat!("harmos::", stringify!($ty));
43 const FIELDS: &'static [graph::Field<declaration::Definition>] = &[graph::Field {
44 name: Cow::Borrowed("value"),
45 tag: 1,
46 kind: graph::Kind::$kind,
47 cardinality: Cardinality::Required,
48 }];
49 const MARKER: &'static [u8] = &declaration::encode::<{
50 declaration::encoded_len(Self::NAME, Self::FIELDS)
51 }>(Self::NAME, Self::FIELDS);
52 }
53 )*};
54}
55
56wrapper!(bool => Bool, u32 => U32, u64 => U64, i32 => I32, i64 => I64, f32 => F32, f64 => F64, String => String, Vec<u8> => Bytes);
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
65#[serde(rename_all = "snake_case")]
66pub enum Cardinality {
67 Required,
68 Optional,
69 Repeated,
70 Variant,
71}
72
73#[derive(Debug, thiserror::Error)]
74pub enum Error {
75 #[error(transparent)]
76 Graph(#[from] graph::Error),
77}
78
79pub trait Described: 'static {
83 const FIELD_KIND: graph::Kind<declaration::Definition> = graph::Kind::Message { definition: Self::DEFINITION };
84
85 const NAME: &'static str;
86 const FIELDS: &'static [graph::Field<declaration::Definition>];
87 const MARKER: &'static [u8];
88
89 const DEFAULT_VARIANT: Option<usize> = Some(0);
90
91 const DEFINITION: declaration::Definition = declaration::Definition::of::<Self>();
92}
93
94impl Described for () {
97 const NAME: &'static str = "harmos::unit";
98 const FIELDS: &'static [graph::Field<declaration::Definition>] = &[];
99 const MARKER: &'static [u8] = &declaration::encode::<{ declaration::encoded_len(Self::NAME, Self::FIELDS) }>(Self::NAME, Self::FIELDS);
100}
101
102impl<T: Described> Described for Option<T> {
103 const NAME: &'static str = declaration::Name::new("harmos::Optional", &[T::NAME]).as_str();
104 const FIELDS: &'static [graph::Field<declaration::Definition>] = &[graph::Field {
105 name: Cow::Borrowed("value"),
106 tag: 1,
107 kind: T::FIELD_KIND,
108 cardinality: Cardinality::Optional,
109 }];
110 const MARKER: &'static [u8] =
111 declaration::encode_buffer::<2048>(Self::NAME, Self::FIELDS).split_at(declaration::encoded_len(Self::NAME, Self::FIELDS)).0;
112}
113
114fn diagnostic_name(name: &str) -> String {
119 if name.len() <= MAX_NAME_BYTES {
120 return name.to_owned();
121 }
122 let mut end = MAX_NAME_BYTES - 3;
123 while !name.is_char_boundary(end) {
124 end -= 1;
125 }
126 let mut result = String::with_capacity(MAX_NAME_BYTES);
127 result.push_str(&name[..end]);
128 result.push_str("...");
129 result
130}
131
132