Skip to main content

braze_sync/resource/
mod.rs

1//! Domain types for the four resources braze-sync manages.
2//!
3//! See IMPLEMENTATION.md §6 for the complete type contracts. Adding a new
4//! variant to [`Resource`] / [`ResourceKind`] forces every `match` site in
5//! `diff/`, `fs/`, and `braze/` to be updated — that compiler-enforced
6//! exhaustiveness is the central reason braze-sync is written in Rust
7//! (§2.4).
8
9pub mod catalog;
10pub mod content_block;
11pub mod custom_attribute;
12pub mod email_template;
13pub mod tag;
14
15pub use catalog::{Catalog, CatalogField, CatalogFieldType};
16pub use content_block::{ContentBlock, ContentBlockState};
17pub use custom_attribute::{CustomAttribute, CustomAttributeRegistry, CustomAttributeType};
18pub use email_template::EmailTemplate;
19pub use tag::{Tag, TagRegistry};
20
21/// Every resource type braze-sync manages, as a single sum type.
22///
23/// Adding a variant here will produce match-exhaustiveness errors at every
24/// downstream site that consumes a `Resource`. That is intentional.
25#[derive(Debug, Clone, PartialEq)]
26pub enum Resource {
27    CatalogSchema(Catalog),
28    ContentBlock(ContentBlock),
29    EmailTemplate(EmailTemplate),
30    CustomAttributeRegistry(CustomAttributeRegistry),
31    TagRegistry(TagRegistry),
32}
33
34/// Lightweight tag for filtering / CLI args. Mirrors [`Resource`] but
35/// without the payload.
36#[derive(
37    Debug,
38    Clone,
39    Copy,
40    PartialEq,
41    Eq,
42    PartialOrd,
43    Ord,
44    Hash,
45    clap::ValueEnum,
46    serde::Serialize,
47    serde::Deserialize,
48)]
49#[clap(rename_all = "snake_case")]
50#[serde(rename_all = "snake_case")]
51pub enum ResourceKind {
52    CatalogSchema,
53    ContentBlock,
54    EmailTemplate,
55    CustomAttribute,
56    Tag,
57}
58
59impl ResourceKind {
60    pub fn as_str(&self) -> &'static str {
61        match self {
62            Self::CatalogSchema => "catalog_schema",
63            Self::ContentBlock => "content_block",
64            Self::EmailTemplate => "email_template",
65            Self::CustomAttribute => "custom_attribute",
66            Self::Tag => "tag",
67        }
68    }
69
70    pub fn all() -> &'static [Self] {
71        &[
72            Self::CatalogSchema,
73            Self::ContentBlock,
74            Self::EmailTemplate,
75            Self::CustomAttribute,
76            Self::Tag,
77        ]
78    }
79}
80
81impl Resource {
82    pub fn kind(&self) -> ResourceKind {
83        match self {
84            Self::CatalogSchema(_) => ResourceKind::CatalogSchema,
85            Self::ContentBlock(_) => ResourceKind::ContentBlock,
86            Self::EmailTemplate(_) => ResourceKind::EmailTemplate,
87            Self::CustomAttributeRegistry(_) => ResourceKind::CustomAttribute,
88            Self::TagRegistry(_) => ResourceKind::Tag,
89        }
90    }
91}