use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum FhirPrimitiveType {
Boolean,
Integer,
String,
Date,
DateTime,
Instant,
Time,
Decimal,
Uri,
Url,
Canonical,
Code,
Oid,
Id,
Markdown,
Base64Binary,
UnsignedInt,
PositiveInt,
}
impl FhirPrimitiveType {
pub fn from_fhir_type(fhir_type: &str) -> Option<Self> {
match fhir_type {
"boolean" => Some(Self::Boolean),
"integer" => Some(Self::Integer),
"string" => Some(Self::String),
"date" => Some(Self::Date),
"dateTime" => Some(Self::DateTime),
"instant" => Some(Self::Instant),
"time" => Some(Self::Time),
"decimal" => Some(Self::Decimal),
"uri" => Some(Self::Uri),
"url" => Some(Self::Url),
"canonical" => Some(Self::Canonical),
"code" => Some(Self::Code),
"oid" => Some(Self::Oid),
"id" => Some(Self::Id),
"markdown" => Some(Self::Markdown),
"base64Binary" => Some(Self::Base64Binary),
"unsignedInt" => Some(Self::UnsignedInt),
"positiveInt" => Some(Self::PositiveInt),
_ => None,
}
}
pub fn variant_name(&self) -> &'static str {
match self {
Self::Boolean => "Boolean",
Self::Integer => "Integer",
Self::String => "String",
Self::Date => "Date",
Self::DateTime => "DateTime",
Self::Instant => "Instant",
Self::Time => "Time",
Self::Decimal => "Decimal",
Self::Uri => "Uri",
Self::Url => "Url",
Self::Canonical => "Canonical",
Self::Code => "Code",
Self::Oid => "Oid",
Self::Id => "Id",
Self::Markdown => "Markdown",
Self::Base64Binary => "Base64Binary",
Self::UnsignedInt => "UnsignedInt",
Self::PositiveInt => "PositiveInt",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum FhirFieldType {
Primitive(FhirPrimitiveType),
Complex(String), Reference, BackboneElement(String), }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldInfo {
pub field_type: FhirFieldType,
pub min: u32,
pub max: Option<u32>, pub is_choice_type: bool,
pub choice_types: Vec<String>, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypeMetadata {
pub name: String,
pub fields: HashMap<String, FieldInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetadataRegistry {
pub types: HashMap<String, TypeMetadata>,
}
impl MetadataRegistry {
pub fn new() -> Self {
Self {
types: HashMap::new(),
}
}
pub fn add_type(&mut self, type_metadata: TypeMetadata) {
self.types.insert(type_metadata.name.clone(), type_metadata);
}
pub fn resolve_path(&self, path: &str) -> Option<&FhirFieldType> {
let parts: Vec<&str> = path.split('.').collect();
if parts.is_empty() {
return None;
}
let mut current_type_name = parts[0];
let mut current_type = self.types.get(current_type_name)?;
for &field_name in &parts[1..] {
let field_info = current_type.fields.get(field_name)?;
if field_name == *parts.last().unwrap() {
return Some(&field_info.field_type);
}
match &field_info.field_type {
FhirFieldType::Complex(type_name) | FhirFieldType::BackboneElement(type_name) => {
current_type_name = type_name;
current_type = self.types.get(current_type_name)?;
}
FhirFieldType::Reference => {
return None;
}
FhirFieldType::Primitive(_) => {
return None;
}
}
}
None
}
}
impl Default for MetadataRegistry {
fn default() -> Self {
Self::new()
}
}