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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Error types for sigil-stitch.
use snafu::prelude::*;
/// Errors returned by sigil-stitch operations.
#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
#[non_exhaustive]
pub enum SigilStitchError {
/// Format string argument count mismatch.
#[snafu(display(
"format string {format:?} expects {expected} args but got {actual}\n \
specifiers: {expected_specifiers:?}\n \
arg kinds: {actual_arg_kinds:?}"
))]
FormatArgCount {
/// The format string that was passed.
format: String,
/// Number of argument slots in the format string.
expected: usize,
/// Number of arguments actually provided.
actual: usize,
/// The sequence of specifier names from the format string (e.g., `["%T", "%S", "%L"]`).
expected_specifiers: Vec<String>,
/// The variant names of the provided args (e.g., `["TypeName", "Literal", "Literal"]`).
actual_arg_kinds: Vec<String>,
},
/// A required name or filename field was empty.
#[snafu(display("{builder}::build() failed: 'name' must not be empty"))]
EmptyName {
/// The builder type that detected the error.
builder: &'static str,
},
/// Unbalanced begin_control_flow / end_control_flow calls.
#[snafu(display(
"unbalanced control flow: indent depth is {depth} (expected 0). \
Check begin_control_flow / end_control_flow calls."
))]
UnbalancedIndent {
/// The indent depth at build time.
depth: i32,
},
/// Error during code rendering.
#[snafu(display("{context}: {message}"))]
Render {
/// What was being rendered.
context: String,
/// The error message.
message: String,
},
/// Error in template parsing or application.
#[snafu(display("template error: {message}"))]
Template {
/// The error message.
message: String,
},
/// I/O error (e.g., writing project files).
#[snafu(display("{context}"))]
Io {
/// The underlying I/O error.
source: std::io::Error,
/// What was being done when the error occurred.
context: String,
},
/// Module path validation failure.
#[snafu(display("invalid module path: {message}"))]
InvalidModulePath {
/// The error message.
message: String,
},
/// Invalid format specifier in a format string.
#[snafu(display("invalid format specifier '%{specifier}' in format string {format:?}"))]
InvalidFormatSpecifier {
/// The format string that contained the invalid specifier.
format: String,
/// The unrecognized character after `%`.
specifier: char,
},
/// Duplicate field name in a type specification.
#[snafu(display("duplicate field name {field_name:?} in type {type_name:?}"))]
DuplicateFieldName {
/// The name of the type that contains the duplicate.
type_name: String,
/// The duplicated field name.
field_name: String,
},
/// Invalid TypeAlias or Newtype declaration.
#[snafu(display("invalid {kind} {type_name:?}: {reason}"))]
InvalidTypeAlias {
/// The kind of declaration ("TypeAlias" or "Newtype").
kind: &'static str,
/// The type name.
type_name: String,
/// The reason the declaration is invalid.
reason: String,
},
/// Duplicate filename in a project specification.
#[snafu(display("duplicate filename {filename:?} in ProjectSpec (appears {count} times)"))]
DuplicateFileName {
/// The duplicated filename.
filename: String,
/// How many times it appeared.
count: usize,
},
/// FileSpec has no language set (e.g. after deserialization).
#[snafu(display(
"FileSpec {filename:?} has no language — call .with_lang() after deserialization \
or use FileSpec::builder_with() to set one"
))]
MissingLang {
/// The filename of the FileSpec.
filename: String,
},
/// Invalid enum declaration.
#[snafu(display("invalid enum {type_name:?}: {reason}"))]
InvalidEnum {
/// The type name.
type_name: String,
/// The reason the declaration is invalid.
reason: String,
},
}