Skip to main content

braze_sync/resource/
mod.rs

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