1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use serde_cbor::{to_vec, value::to_value};
4use serde_json::Value;
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
9pub struct Meta {
10 #[serde(default, skip_serializing_if = "Option::is_none")]
11 pub created_at: Option<String>,
12 #[serde(default, skip_serializing_if = "Option::is_none")]
13 pub updated_at: Option<String>,
14}
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
18pub struct AnswerSet {
19 pub form_id: String,
20 pub spec_version: String,
21 pub answers: Value,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub meta: Option<Meta>,
24}
25
26impl AnswerSet {
27 pub fn new(form_id: impl Into<String>, spec_version: impl Into<String>) -> Self {
29 Self {
30 form_id: form_id.into(),
31 spec_version: spec_version.into(),
32 answers: Value::Object(Default::default()),
33 meta: None,
34 }
35 }
36
37 pub fn to_cbor(&self) -> Result<Vec<u8>, serde_cbor::Error> {
39 let canonical = to_value(self)?;
40 to_vec(&canonical)
41 }
42
43 pub fn to_json_pretty(&self) -> Result<String, serde_json::Error> {
45 serde_json::to_string_pretty(self)
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
51pub struct ProgressState {
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub current_step: Option<String>,
54 pub completed: bool,
55 #[serde(default, skip_serializing_if = "Vec::is_empty")]
56 pub history: Vec<String>,
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
61pub struct ValidationError {
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub question_id: Option<String>,
64 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub path: Option<String>,
66 pub message: String,
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 pub code: Option<String>,
69 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
70 pub params: BTreeMap<String, String>,
71}
72
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
75pub struct ValidationResult {
76 pub valid: bool,
77 #[serde(default, skip_serializing_if = "Vec::is_empty")]
78 pub errors: Vec<ValidationError>,
79 #[serde(default, skip_serializing_if = "Vec::is_empty")]
80 pub missing_required: Vec<String>,
81 #[serde(default, skip_serializing_if = "Vec::is_empty")]
82 pub unknown_fields: Vec<String>,
83}