Skip to main content

merman_render/svg/icon_registry/
error.rs

1use super::IconRegistryResourceLimitId;
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5#[non_exhaustive]
6pub enum IconRegistryBuildErrorKind {
7    ResourceLimitExceeded,
8    InvalidUtf8,
9    InvalidJson,
10    DuplicateJsonKey,
11    InvalidSchema,
12    InvalidIdentifier,
13    InvalidGeometry,
14    InvalidXml,
15    DuplicateIcon,
16    AliasCycle,
17    MissingAliasParent,
18    ArithmeticOverflow,
19    AllocationFailed,
20}
21
22impl IconRegistryBuildErrorKind {
23    pub const fn stable_id(self) -> &'static str {
24        match self {
25            Self::ResourceLimitExceeded => "resource_limit_exceeded",
26            Self::InvalidUtf8 => "invalid_utf8",
27            Self::InvalidJson => "invalid_json",
28            Self::DuplicateJsonKey => "duplicate_json_key",
29            Self::InvalidSchema => "invalid_schema",
30            Self::InvalidIdentifier => "invalid_identifier",
31            Self::InvalidGeometry => "invalid_geometry",
32            Self::InvalidXml => "invalid_xml",
33            Self::DuplicateIcon => "duplicate_icon",
34            Self::AliasCycle => "alias_cycle",
35            Self::MissingAliasParent => "missing_alias_parent",
36            Self::ArithmeticOverflow => "arithmetic_overflow",
37            Self::AllocationFailed => "allocation_failed",
38        }
39    }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct IconRegistryBuildError {
44    kind: IconRegistryBuildErrorKind,
45    pack_index: Option<usize>,
46    registration_name: Option<String>,
47    limit: Option<IconRegistryResourceLimitId>,
48    actual: Option<u64>,
49    maximum: Option<u64>,
50    message: String,
51}
52
53impl IconRegistryBuildError {
54    pub(super) fn new(
55        kind: IconRegistryBuildErrorKind,
56        pack_index: impl Into<Option<usize>>,
57        message: impl Into<String>,
58    ) -> Self {
59        Self {
60            kind,
61            pack_index: pack_index.into(),
62            registration_name: None,
63            limit: None,
64            actual: None,
65            maximum: None,
66            message: message.into(),
67        }
68    }
69
70    pub(super) fn with_registration_name(mut self, registration_name: Option<&str>) -> Self {
71        self.registration_name = registration_name.map(str::to_owned);
72        self
73    }
74
75    pub(super) fn with_limit(
76        mut self,
77        limit: IconRegistryResourceLimitId,
78        actual: impl TryInto<u64>,
79        maximum: impl TryInto<u64>,
80    ) -> Self {
81        self.limit = Some(limit);
82        self.actual = actual.try_into().ok();
83        self.maximum = maximum.try_into().ok();
84        self
85    }
86
87    pub const fn kind(&self) -> IconRegistryBuildErrorKind {
88        self.kind
89    }
90
91    pub const fn pack_index(&self) -> Option<usize> {
92        self.pack_index
93    }
94
95    pub fn registration_name(&self) -> Option<&str> {
96        self.registration_name.as_deref()
97    }
98
99    pub const fn limit_id(&self) -> Option<&'static str> {
100        match self.limit {
101            Some(limit) => Some(limit.stable_id()),
102            None => None,
103        }
104    }
105
106    pub const fn limit(&self) -> Option<IconRegistryResourceLimitId> {
107        self.limit
108    }
109
110    pub const fn actual(&self) -> Option<u64> {
111        self.actual
112    }
113
114    pub const fn maximum(&self) -> Option<u64> {
115        self.maximum
116    }
117}
118
119impl fmt::Display for IconRegistryBuildError {
120    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
121        write!(
122            formatter,
123            "icon registry build failed ({})",
124            self.kind.stable_id()
125        )?;
126        if let Some(pack_index) = self.pack_index {
127            write!(formatter, " in pack {pack_index}")?;
128        }
129        if let Some(registration_name) = &self.registration_name {
130            write!(formatter, " registered as `{registration_name}`")?;
131        }
132        write!(formatter, ": {}", self.message)?;
133        if let Some(limit) = self.limit {
134            write!(formatter, " [{}", limit.stable_id())?;
135            if let Some(actual) = self.actual {
136                write!(formatter, " actual={actual}")?;
137            }
138            if let Some(maximum) = self.maximum {
139                write!(formatter, " max={maximum}")?;
140            }
141            formatter.write_str("]")?;
142        }
143        Ok(())
144    }
145}
146
147impl std::error::Error for IconRegistryBuildError {}