#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CatalogueEntry {
pub message_name: &'static str,
pub namespace: &'static str,
pub business_area: &'static str,
pub has_model: bool,
}
pub mod data;
mod generated;
use crate::metadata::MessageDescriptor;
use crate::{MessageFamily, MessageIdentifier};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CoverageState {
Available { required_feature: &'static str },
KnownUnavailable,
Unknown,
}
pub trait Catalogue {
fn lookup(&self, id: &MessageIdentifier) -> Option<&'static MessageDescriptor>;
fn list_family(&self, family: &MessageFamily) -> &'static [MessageDescriptor];
fn versions(&self, family: &MessageFamily) -> &'static [MessageDescriptor];
fn latest(&self, family: &MessageFamily) -> Option<&'static MessageDescriptor>;
fn by_namespace(&self, namespace: &str) -> Option<&'static MessageDescriptor>;
fn by_root(&self, namespace: &str, root: &str) -> Option<&'static MessageDescriptor>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SchemaCatalogue;
pub static SCHEMA_CATALOGUE: SchemaCatalogue = SchemaCatalogue;
impl Catalogue for SchemaCatalogue {
fn lookup(&self, id: &MessageIdentifier) -> Option<&'static MessageDescriptor> {
lookup_descriptor(id.as_str())
}
fn list_family(&self, family: &MessageFamily) -> &'static [MessageDescriptor] {
list_family(family.as_str())
}
fn versions(&self, family: &MessageFamily) -> &'static [MessageDescriptor] {
versions(family.as_str())
}
fn latest(&self, family: &MessageFamily) -> Option<&'static MessageDescriptor> {
latest(family.as_str())
}
fn by_namespace(&self, namespace: &str) -> Option<&'static MessageDescriptor> {
by_namespace(namespace)
}
fn by_root(&self, namespace: &str, root: &str) -> Option<&'static MessageDescriptor> {
by_root(namespace, root)
}
}
pub fn all() -> &'static [CatalogueEntry] {
data::ENTRIES
}
pub fn from_message_name(message_name: &str) -> Option<&'static CatalogueEntry> {
data::BY_NAME.get(message_name)
}
pub fn from_namespace(namespace: &str) -> Option<&'static CatalogueEntry> {
by_namespace(namespace).and_then(|descriptor| data::BY_NAME.get(descriptor.identity))
}
pub fn contains(message_name: &str) -> bool {
data::BY_NAME.contains_key(message_name)
}
pub fn lookup_descriptor(message_id: &str) -> Option<&'static MessageDescriptor> {
let descriptors = crate::metadata::all();
debug_assert_eq!(descriptors.len(), generated::DESCRIPTOR_COUNT);
generated::BY_ID
.get(message_id)
.and_then(|ordinal| descriptors.get(*ordinal))
}
pub fn lookup_field(
message_id: &str,
logical_path: &str,
) -> Option<&'static crate::metadata::FieldDescriptor> {
lookup_descriptor(message_id)?
.fields
.iter()
.find(|field| field.logical_path == logical_path)
}
pub fn list_family(family: &str) -> &'static [MessageDescriptor] {
let descriptors = crate::metadata::all();
generated::FAMILY_RANGES
.get(family)
.and_then(|(start, length)| descriptors.get(*start..(*start + *length)))
.unwrap_or(&[])
}
pub fn versions(family: &str) -> &'static [MessageDescriptor] {
list_family(family)
}
pub fn latest(family: &str) -> Option<&'static MessageDescriptor> {
list_family(family).last()
}
pub fn by_namespace(namespace: &str) -> Option<&'static MessageDescriptor> {
let descriptors = crate::metadata::all();
generated::BY_NAMESPACE
.get(namespace)
.and_then(|ordinal| descriptors.get(*ordinal))
}
pub fn by_root(namespace: &str, root: &str) -> Option<&'static MessageDescriptor> {
let key = format!("{namespace}\u{1f}{root}");
let descriptors = crate::metadata::all();
generated::BY_ROOT
.get(&key)
.and_then(|ordinal| descriptors.get(*ordinal))
}
pub fn coverage(message_id: &str) -> CoverageState {
if let Some(descriptor) = lookup_descriptor(message_id) {
CoverageState::Available {
required_feature: descriptor.required_feature,
}
} else if from_message_name(message_id).is_some() {
CoverageState::KnownUnavailable
} else {
CoverageState::Unknown
}
}