#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, doc(auto_cfg))]
#[cfg(feature = "codegen")]
#[doc(hidden)]
pub mod attrs;
#[cfg(feature = "codegen")]
#[doc(hidden)]
pub mod codegen;
#[cfg(feature = "codegen")]
#[doc(hidden)]
pub mod ir;
#[cfg(feature = "codegen")]
#[doc(hidden)]
pub mod iri;
mod value;
#[cfg(any(feature = "serde-json", feature = "sonic-rs", feature = "jstrict"))]
mod backends;
#[cfg(feature = "chrono")]
mod interop_chrono;
pub use value::{JsonValue, ToJsonValue};
pub trait Expandable {
fn expand<V: JsonValue>(&self) -> V;
}
pub trait ExpandableTypeValue {
fn to_type_array<V: JsonValue>(&self) -> V;
}
pub trait ExpandableLanguageMap {
fn to_expanded_language_map<V: JsonValue>(&self) -> V;
}
fn language_entries<'a, V: JsonValue, I>(entries: I) -> V
where
I: IntoIterator<Item = (&'a str, &'a str)>,
{
V::array(
entries
.into_iter()
.map(|(lang, text)| V::object([("@value".to_string(), V::string(text)), ("@language".to_string(), V::string(lang))])),
)
}
impl<K: AsRef<str>, T: AsRef<str>, S> ExpandableLanguageMap for std::collections::HashMap<K, T, S> {
fn to_expanded_language_map<V: JsonValue>(&self) -> V {
let mut entries: Vec<(&str, &str)> = self.iter().map(|(k, v)| (k.as_ref(), v.as_ref())).collect();
entries.sort_unstable_by_key(|(lang, _)| *lang);
language_entries(entries)
}
}
impl<K: AsRef<str>, T: AsRef<str>> ExpandableLanguageMap for std::collections::BTreeMap<K, T> {
fn to_expanded_language_map<V: JsonValue>(&self) -> V {
language_entries(self.iter().map(|(k, v)| (k.as_ref(), v.as_ref())))
}
}
#[cfg(feature = "codegen")]
#[doc(hidden)]
#[must_use]
pub fn derive_expandable(input: &syn::DeriveInput, runtime: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
match codegen::generate(input, runtime) {
Ok(ts) => ts,
Err(err) => err.to_compile_error(),
}
}