1pub mod declaration;
15pub mod graph;
16mod payload;
17
18pub use declaration::{Field, Kind};
21pub use payload::{Event, PathElement, PayloadError, Scalar, Validator, VisitError};
22
23use std::borrow::Cow;
27use serde::{Deserialize, Serialize};
29pub const MAX_DEPTH: usize = 32;
34pub const MAX_NAME_BYTES: usize = 256;
35
36macro_rules! wrapper {
40 ($($ty:ty => $kind:ident),* $(,)?) => {$(
41 impl Described for $ty {
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 NAME: &'static str;
84 const FIELDS: &'static [graph::Field<declaration::Definition>];
85 const MARKER: &'static [u8];
86
87 const DEFAULT_VARIANT: Option<usize> = Some(0);
88
89 const DEFINITION: declaration::Definition = declaration::Definition::of::<Self>();
90}
91
92impl Described for () {
95 const NAME: &'static str = "harmos::unit";
96 const FIELDS: &'static [graph::Field<declaration::Definition>] = &[];
97 const MARKER: &'static [u8] = &declaration::encode::<{ declaration::encoded_len(Self::NAME, Self::FIELDS) }>(Self::NAME, Self::FIELDS);
98}
99
100fn diagnostic_name(name: &str) -> String {
105 if name.len() <= MAX_NAME_BYTES {
106 return name.to_owned();
107 }
108 let mut end = MAX_NAME_BYTES - 3;
109 while !name.is_char_boundary(end) {
110 end -= 1;
111 }
112 let mut result = String::with_capacity(MAX_NAME_BYTES);
113 result.push_str(&name[..end]);
114 result.push_str("...");
115 result
116}
117
118