appcore_filemaker/
error.rs1use std::fmt;
12
13use thiserror::Error;
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum ErrorCode {
18 SchemaSyntax,
20 SchemaVersion,
22 SchemaField,
24 DataType,
26 DataCycle,
28 AssetSandbox,
30 AssetInvalid,
32 FontMissing,
34 GeometryInvalid,
36 LayoutInvalid,
38 LayoutNonConvergent,
40 PatchInvalid,
42 PatchLocked,
44 ExportUnsupported,
46 ExportWrite,
48 LimitExceeded,
50 Cancelled,
52 Validation,
54}
55
56impl ErrorCode {
57 #[must_use]
59 pub const fn as_str(self) -> &'static str {
60 match self {
61 Self::SchemaSyntax => "FM-SCHEMA-SYNTAX",
62 Self::SchemaVersion => "FM-SCHEMA-VERSION",
63 Self::SchemaField => "FM-SCHEMA-FIELD",
64 Self::DataType => "FM-DATA-TYPE",
65 Self::DataCycle => "FM-DATA-CYCLE",
66 Self::AssetSandbox => "FM-ASSET-SANDBOX",
67 Self::AssetInvalid => "FM-ASSET-INVALID",
68 Self::FontMissing => "FM-FONT-MISSING",
69 Self::GeometryInvalid => "FM-GEOM-INVALID",
70 Self::LayoutInvalid => "FM-LAYOUT-INVALID",
71 Self::LayoutNonConvergent => "FM-LAYOUT-NON-CONVERGENT",
72 Self::PatchInvalid => "FM-PATCH-INVALID",
73 Self::PatchLocked => "FM-PATCH-LOCKED",
74 Self::ExportUnsupported => "FM-EXPORT-UNSUPPORTED",
75 Self::ExportWrite => "FM-EXPORT-WRITE",
76 Self::LimitExceeded => "FM-LIMIT-EXCEEDED",
77 Self::Cancelled => "FM-CANCELLED",
78 Self::Validation => "FM-VALIDATION",
79 }
80 }
81}
82
83#[derive(Debug, Error)]
85#[error("{code}: {message}")]
86pub struct FileMakerError {
87 code: CodeDisplay,
88 message: String,
89 source_path: Option<String>,
90}
91
92impl FileMakerError {
93 #[must_use]
95 pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
96 let mut message = message.into();
97 message.truncate(1_024);
98 Self {
99 code: CodeDisplay(code),
100 message,
101 source_path: None,
102 }
103 }
104
105 #[must_use]
107 pub fn at(mut self, source_path: impl Into<String>) -> Self {
108 let mut source_path = source_path.into();
109 source_path.truncate(512);
110 self.source_path = Some(source_path);
111 self
112 }
113
114 #[must_use]
116 pub const fn code(&self) -> ErrorCode {
117 self.code.0
118 }
119
120 #[must_use]
122 pub fn message(&self) -> &str {
123 &self.message
124 }
125
126 #[must_use]
128 pub fn source_path(&self) -> Option<&str> {
129 self.source_path.as_deref()
130 }
131}
132
133#[derive(Debug)]
134struct CodeDisplay(ErrorCode);
135
136impl fmt::Display for CodeDisplay {
137 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
138 formatter.write_str(self.0.as_str())
139 }
140}
141
142pub type Result<T> = std::result::Result<T, FileMakerError>;