1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::{entity::EntityDescriptorConst, AnyEntity, WorkloadV2};

#[derive(Serialize, Deserialize, JsonSchema, PartialEq, Eq, Clone, Debug)]
pub struct AppV1Spec {
    /// A list of alias names for the app.
    /// Aliases can be used to access the app through app domains.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub aliases: Vec<String>,

    /// The primary workload to execute.
    pub workload: WorkloadV2,
}

#[derive(Serialize, Deserialize, JsonSchema, PartialEq, Eq, Clone, Debug)]
pub struct AppStateV1 {}

impl EntityDescriptorConst for AppV1Spec {
    const NAMESPACE: &'static str = "wasmer.io";
    const NAME: &'static str = "App";
    const VERSION: &'static str = "1-alpha1";
    const KIND: &'static str = "wasmer.io/App.v1";

    type Spec = AppV1Spec;
    type State = AppStateV1;
}

pub type AppV1 = super::Entity<AppV1Spec, AnyEntity>;

#[cfg(test)]
mod tests {
    use pretty_assertions::assert_eq;

    use crate::schema::EntityMeta;

    use super::*;

    /// Tests serilization and deserialization of the [`AppV1`] struct.
    #[test]
    fn test_deser_app_v1_sparse() {
        let inp = r#"
kind: wasmer.io/App.v1
meta:
  name: my-app
spec:
  workload:
    source: theduke/amaze
"#;

        let a1 = serde_yaml::from_str::<AppV1>(inp).unwrap();

        assert_eq!(
            a1,
            AppV1 {
                meta: EntityMeta::new("my-app"),
                spec: AppV1Spec {
                    aliases: Vec::new(),
                    workload: crate::schema::WorkloadV2 {
                        source: "theduke/amaze".parse().unwrap(),
                    },
                },
                children: None,
            },
        );
    }

    #[test]
    fn test_deser_app_v1_full() {
        let inp = r#"
kind: wasmer.io/App.v1
meta:
  name: my-app
  description: hello
  labels:
    "my/label": "value"
  annotations:
    "my/annotation": {nested: [1, 2, 3]}
spec:
  aliases:
    - a
    - b
  workload:
    source: "theduke/my-app"
"#;

        let a1 = serde_yaml::from_str::<AppV1>(inp).unwrap();

        let expected = AppV1 {
            meta: EntityMeta {
                name: "my-app".to_string(),
                description: Some("hello".to_string()),
                labels: vec![("my/label".to_string(), "value".to_string())]
                    .into_iter()
                    .collect(),
                annotations: vec![(
                    "my/annotation".to_string(),
                    serde_json::json!({
                        "nested": [1, 2, 3],
                    }),
                )]
                .into_iter()
                .collect(),
                parent: None,
            },
            spec: AppV1Spec {
                aliases: vec!["a".to_string(), "b".to_string()],
                workload: WorkloadV2 {
                    source: "theduke/my-app".parse().unwrap(),
                },
            },
            children: None,
        };

        assert_eq!(a1, expected,);
    }
}