1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub enum FhirPrimitiveType {
12 Boolean,
13 Integer,
14 String,
15 Date,
16 DateTime,
17 Instant,
18 Time,
19 Decimal,
20 Uri,
21 Url,
22 Canonical,
23 Code,
24 Oid,
25 Id,
26 Markdown,
27 Base64Binary,
28 UnsignedInt,
29 PositiveInt,
30}
31
32impl FhirPrimitiveType {
33 pub fn from_fhir_type(fhir_type: &str) -> Option<Self> {
35 match fhir_type {
36 "boolean" => Some(Self::Boolean),
37 "integer" => Some(Self::Integer),
38 "string" => Some(Self::String),
39 "date" => Some(Self::Date),
40 "dateTime" => Some(Self::DateTime),
41 "instant" => Some(Self::Instant),
42 "time" => Some(Self::Time),
43 "decimal" => Some(Self::Decimal),
44 "uri" => Some(Self::Uri),
45 "url" => Some(Self::Url),
46 "canonical" => Some(Self::Canonical),
47 "code" => Some(Self::Code),
48 "oid" => Some(Self::Oid),
49 "id" => Some(Self::Id),
50 "markdown" => Some(Self::Markdown),
51 "base64Binary" => Some(Self::Base64Binary),
52 "unsignedInt" => Some(Self::UnsignedInt),
53 "positiveInt" => Some(Self::PositiveInt),
54 _ => None,
55 }
56 }
57
58 pub fn variant_name(&self) -> &'static str {
60 match self {
61 Self::Boolean => "Boolean",
62 Self::Integer => "Integer",
63 Self::String => "String",
64 Self::Date => "Date",
65 Self::DateTime => "DateTime",
66 Self::Instant => "Instant",
67 Self::Time => "Time",
68 Self::Decimal => "Decimal",
69 Self::Uri => "Uri",
70 Self::Url => "Url",
71 Self::Canonical => "Canonical",
72 Self::Code => "Code",
73 Self::Oid => "Oid",
74 Self::Id => "Id",
75 Self::Markdown => "Markdown",
76 Self::Base64Binary => "Base64Binary",
77 Self::UnsignedInt => "UnsignedInt",
78 Self::PositiveInt => "PositiveInt",
79 }
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85pub enum FhirFieldType {
86 Primitive(FhirPrimitiveType),
87 Complex(String), Reference, BackboneElement(String), }
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct FieldInfo {
95 pub field_type: FhirFieldType,
96 pub min: u32,
97 pub max: Option<u32>, pub is_choice_type: bool,
99 pub choice_types: Vec<String>, }
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct TypeMetadata {
105 pub name: String,
106 pub fields: HashMap<String, FieldInfo>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct MetadataRegistry {
112 pub types: HashMap<String, TypeMetadata>,
113}
114
115impl MetadataRegistry {
116 pub fn new() -> Self {
117 Self {
118 types: HashMap::new(),
119 }
120 }
121
122 pub fn add_type(&mut self, type_metadata: TypeMetadata) {
123 self.types.insert(type_metadata.name.clone(), type_metadata);
124 }
125
126 pub fn resolve_path(&self, path: &str) -> Option<&FhirFieldType> {
128 let parts: Vec<&str> = path.split('.').collect();
129 if parts.is_empty() {
130 return None;
131 }
132
133 let mut current_type_name = parts[0];
135 let mut current_type = self.types.get(current_type_name)?;
136
137 for &field_name in &parts[1..] {
139 let field_info = current_type.fields.get(field_name)?;
140
141 if field_name == *parts.last().unwrap() {
143 return Some(&field_info.field_type);
144 }
145
146 match &field_info.field_type {
148 FhirFieldType::Complex(type_name) | FhirFieldType::BackboneElement(type_name) => {
149 current_type_name = type_name;
150 current_type = self.types.get(current_type_name)?;
151 }
152 FhirFieldType::Reference => {
153 return None;
155 }
156 FhirFieldType::Primitive(_) => {
157 return None;
159 }
160 }
161 }
162
163 None
164 }
165}
166
167impl Default for MetadataRegistry {
168 fn default() -> Self {
169 Self::new()
170 }
171}