1#![allow(dead_code)]
4use crate::{Rc, Schema, Value, Vec};
5use alloc::collections::BTreeMap;
6use serde::Deserialize;
7
8mod deserialize;
9mod error;
10mod resource_schema_selector;
11
12type String = Rc<str>;
13
14use deserialize::{deserialize_effects, deserialize_resource_schemas};
15pub use error::TargetError;
16
17#[derive(Debug, Clone, Deserialize)]
21#[serde(deny_unknown_fields)]
22pub struct Target {
23 pub name: String,
27
28 pub description: Option<String>,
30
31 pub version: String,
33
34 #[serde(deserialize_with = "deserialize_resource_schemas")]
36 pub resource_schemas: Vec<Rc<Schema>>,
37
38 pub resource_schema_selector: String,
41
42 #[serde(deserialize_with = "deserialize_effects")]
44 pub effects: BTreeMap<String, Rc<Schema>>,
45 #[serde(skip)]
47 pub resource_schema_lookup: BTreeMap<Value, Rc<Schema>>,
48
49 #[serde(skip)]
51 pub default_resource_schema: Option<Rc<Schema>>,
52}
53
54impl Target {
55 pub fn from_json_str(json: &str) -> Result<Self, TargetError> {
56 let mut target: Target = serde_json::from_str(json).map_err(TargetError::from)?;
57
58 if target.resource_schemas.is_empty() {
60 return Err(TargetError::EmptyResourceSchemas(
61 "Target must have at least one resource schema defined".into(),
62 ));
63 }
64
65 if target.effects.is_empty() {
66 return Err(TargetError::EmptyEffectSchemas(
67 "Target must have at least one effect defined".into(),
68 ));
69 }
70
71 resource_schema_selector::populate_target_lookup_fields(&mut target)?;
72 Ok(target)
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 mod deserialize;
79}