use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Pattern {
Primitive(String),
Concept {
codings: Vec<CodingPattern>,
text: Option<String>,
},
Coding(CodingPattern),
Unread {
key: String,
},
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CodingPattern {
pub(super) system: Option<String>,
pub(super) version: Option<String>,
pub(super) code: Option<String>,
pub(super) display: Option<String>,
}
impl CodingPattern {
#[must_use]
pub fn system(&self) -> Option<&str> {
self.system.as_deref()
}
#[must_use]
pub fn version(&self) -> Option<&str> {
self.version.as_deref()
}
#[must_use]
pub fn code(&self) -> Option<&str> {
self.code.as_deref()
}
#[must_use]
pub fn display(&self) -> Option<&str> {
self.display.as_deref()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Slicing {
pub(super) discriminators: Vec<Discriminator>,
pub(super) ordered: bool,
pub(super) rules: SlicingRules,
}
impl Slicing {
#[must_use]
pub fn discriminators(&self) -> &[Discriminator] {
&self.discriminators
}
#[must_use]
pub const fn ordered(&self) -> bool {
self.ordered
}
#[must_use]
pub const fn rules(&self) -> SlicingRules {
self.rules
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Discriminator {
pub(super) kind: DiscriminatorKind,
pub(super) path: String,
}
impl Discriminator {
#[must_use]
pub const fn kind(&self) -> DiscriminatorKind {
self.kind
}
#[must_use]
pub fn path(&self) -> &str {
&self.path
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DiscriminatorKind {
Value,
Exists,
Pattern,
Type,
Profile,
}
impl DiscriminatorKind {
#[must_use]
pub fn from_code(code: &str) -> Option<Self> {
match code {
"value" => Some(Self::Value),
"exists" => Some(Self::Exists),
"pattern" => Some(Self::Pattern),
"type" => Some(Self::Type),
"profile" => Some(Self::Profile),
_ => None,
}
}
}
impl fmt::Display for DiscriminatorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Value => "value",
Self::Exists => "exists",
Self::Pattern => "pattern",
Self::Type => "type",
Self::Profile => "profile",
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SlicingRules {
Closed,
Open,
OpenAtEnd,
}
impl SlicingRules {
#[must_use]
pub fn from_code(code: &str) -> Option<Self> {
match code {
"closed" => Some(Self::Closed),
"open" => Some(Self::Open),
"openAtEnd" => Some(Self::OpenAtEnd),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Invariant {
pub(super) key: String,
pub(super) error: bool,
pub(super) expression: Option<String>,
}
impl Invariant {
#[must_use]
pub fn key(&self) -> &str {
&self.key
}
#[must_use]
pub const fn is_error(&self) -> bool {
self.error
}
#[must_use]
pub fn expression(&self) -> Option<&str> {
self.expression.as_deref()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Binding {
pub(super) strength: BindingStrength,
pub(super) value_set: Option<String>,
}
impl Binding {
#[must_use]
pub const fn strength(&self) -> BindingStrength {
self.strength
}
#[must_use]
pub fn value_set(&self) -> Option<&str> {
self.value_set
.as_deref()
.map(|url| url.split_once('|').map_or(url, |(canonical, _)| canonical))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BindingStrength {
Required,
Extensible,
Preferred,
Example,
}
impl BindingStrength {
#[must_use]
pub fn from_code(code: &str) -> Option<Self> {
match code {
"required" => Some(Self::Required),
"extensible" => Some(Self::Extensible),
"preferred" => Some(Self::Preferred),
"example" => Some(Self::Example),
_ => None,
}
}
}