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
//! Opt-in Rust syntax decoration for integrations, without runtime dependencies.
use ;
/// A generated type and its path of accessor calls from the root snapshot.
///
/// Describes root, group and leaf wrappers only, not locales or message payloads.
/// Syntax-level extension for a consuming framework's generated entrypoint.
///
/// The generator always emits its plain `translations.rs`. An extension adds one
/// independently rendered facade sharing the same upstream modules and contracts.
/// Hooks return Rust syntax nodes, not source strings or user-supplied FTL.
/// Use the re-exported [`syn::parse_quote!`] to construct them. Hooks must not
/// perform I/O. The generated file is syntax-checked before writing; type/name
/// resolution still happens when the consuming crate compiles it.
/// Opaque `Verbatim` syntax nodes are rejected; macro bodies remain opaque tokens.
/// Panics in hooks are not caught or converted into generation diagnostics.
/// Resource registration, framework traits and dependency aliases belong here,
/// not in the generator. The host must arrange the dependencies named by its hooks.
///
/// ```
/// use fluent_typed_codegen::{Extension, Scope, syn::{Attribute, Item, parse_quote}};
///
/// struct Adapter;
///
/// impl Extension for Adapter {
/// fn filename(&self) -> &str {
/// "adapter.rs"
/// }
///
/// fn type_attributes(&self) -> Vec<Attribute> {
/// vec![parse_quote!(#[allow(dead_code)])]
/// }
///
/// fn root_items(&self, scopes: &[Scope]) -> Vec<Item> {
/// let count = scopes.len();
///
/// vec![parse_quote!(pub const SCOPE_COUNT: usize = #count;)]
/// }
/// }
/// ```
///
/// Source strings cannot be passed in place of attributes:
///
/// ```compile_fail
/// use fluent_typed_codegen::syn::Attribute;
///
/// fn attributes() -> Vec<Attribute> {
/// vec!["#[allow(dead_code)]".into()]
/// }
/// ```