openehr-rs 0.3.1

A typed asynchronous client for the EHRDB/openEHR REST API.
Documentation
use serde::{Deserialize, Deserializer, Serialize, de};
use serde_json::Value;
use tracing::info;

#[derive(Deserialize, Serialize)]
pub struct Meta {
    pub href: String,
}

#[derive(Serialize)]
pub struct Resource {
    pub name: String,
    pub mimetype: String,
    #[serde(rename = "type")]
    pub resource_type: String,
    pub href: String,
    pub content: Option<Content>,
}

#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Form {
    pub id: u64,
    pub name: String,
    pub version: String,
    pub created: String,
    pub created_by: String,
    pub updated: String,
    pub updated_by: String,
    pub status: String,
    #[serde(rename = "type")]
    pub form_type: String,
    pub template_id: String,
    pub template_ids: Vec<String>,
    pub resources: Vec<Resource>,
}

#[derive(Deserialize, Serialize)]
pub struct FormResponse {
    pub meta: Meta,
    pub form: Form,
}

#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Content {
    pub form_id: String,
    pub name: String,
    pub rm_type: String,
    pub language: String,
    pub template_languages: Vec<String>,
    pub view_config: ViewConfig,
    pub children: Vec<ChildElement>,
}

#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ChildElement {
    pub name: Option<String>,
    pub localized_name: Option<String>,
    pub rm_type: String,
    pub node_id: String,
    pub min: i32,
    pub max: i32,
    pub aql_path: String,
    pub fid: Option<String>,
    pub form_id: String,
    pub view_config: Option<ViewConfig>,
    pub children: Option<Vec<ChildElement>>,
}

#[derive(Deserialize, Serialize, Clone)]
pub struct ViewConfig {
    pub advanced: Option<AdvancedConfig>,
    pub multiplicity: Option<MultiplicityConfig>,
    pub field: Option<Value>,
}

#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct AdvancedConfig {
    pub hidden: bool,
    pub readonly: bool,
    pub hide_frame: Option<bool>,
}

#[derive(Deserialize, Serialize, Clone)]
pub struct MultiplicityConfig {
    pub min: i32,
    pub max: i32,
}

impl<'de> Deserialize<'de> for Resource {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        struct Intermediate {
            name: String,
            mimetype: String,
            #[serde(rename = "type")]
            resource_type: String,
            href: String,
            content: Option<Value>,
        }

        let intermediate = Intermediate::deserialize(deserializer)?;
        info!("Parsing content for resource {}", intermediate.name);

        let content = if intermediate.name == "edit-form-description" {
            if let Some(content_value) = intermediate.content {
                Some(serde_json::from_value(content_value).map_err(de::Error::custom)?)
            } else {
                None
            }
        } else {
            None
        };

        Ok(Resource {
            name: intermediate.name,
            mimetype: intermediate.mimetype,
            resource_type: intermediate.resource_type,
            href: intermediate.href,
            content,
        })
    }
}