use std::error::Error;
use std::fmt;
use fhir_types::codec::Value;
pub type SeamError = Box<dyn Error + Send + Sync + 'static>;
#[derive(Clone, Copy)]
pub struct ResolveContext<'r> {
pub resource: Option<&'r Value>,
pub root_resource: Option<&'r Value>,
}
fn resource_kind(value: Option<&Value>) -> Option<&str> {
value
.and_then(|value| value.get("resourceType"))
.and_then(Value::as_str)
}
impl fmt::Debug for ResolveContext<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ResolveContext")
.field("resource", &resource_kind(self.resource))
.field("root_resource", &resource_kind(self.root_resource))
.finish()
}
}
pub trait Resolver: fmt::Debug {
fn resolve(
&self,
reference: &str,
context: ResolveContext<'_>,
) -> Result<Option<Value>, SeamError>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Coding<'c> {
pub system: Option<&'c str>,
pub version: Option<&'c str>,
pub code: Option<&'c str>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Coded<'c> {
Code(&'c str),
Coding(Coding<'c>),
Concept(Vec<Coding<'c>>),
}
pub trait Terminology: fmt::Debug {
fn member_of(&self, coded: &Coded<'_>, value_set: &str) -> Result<bool, SeamError>;
fn subsumes(&self, ancestor: &Coding<'_>, descendant: &Coding<'_>) -> Result<bool, SeamError>;
}
pub trait Profiles: fmt::Debug {
fn conforms_to(
&self,
value: &Value,
type_name: Option<&str>,
structure: &str,
) -> Result<bool, SeamError>;
}
pub trait Definitions: fmt::Debug {
fn element_definition(&self, path: &str) -> Result<Option<Value>, SeamError>;
fn in_slice(
&self,
structure: &str,
slice: &str,
value: &Value,
type_name: Option<&str>,
) -> Result<bool, SeamError>;
}