Skip to main content

es_fluent_shared/resource/
errors.rs

1use std::path::{Path, PathBuf};
2
3use crate::CanonicalLanguageIdentifierError;
4use crate::fluent::FluentIdentifierError;
5use crate::namespace::NamespacePathError;
6
7use super::{LocaleRelativeFtlPathError, ResourceKeyError};
8
9/// Errors produced while building a module resource plan.
10#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
11pub enum ResourcePlanError {
12    /// The module domain is not a valid Fluent domain.
13    #[error("invalid Fluent domain '{domain}': {details}")]
14    InvalidDomain {
15        domain: String,
16        details: FluentIdentifierError,
17    },
18    /// The module domain is not a valid resource key segment.
19    #[error("invalid domain resource key '{key}': {details}")]
20    InvalidResourceKey {
21        /// Invalid resource key.
22        key: String,
23        /// Validation details.
24        details: ResourceKeyError,
25    },
26    /// A generated locale-relative resource path is invalid.
27    #[error("invalid locale-relative resource path '{path}': {details}")]
28    InvalidResourcePath {
29        /// Invalid locale-relative path.
30        path: String,
31        /// Validation details.
32        details: LocaleRelativeFtlPathError,
33    },
34    /// A namespace entry is not a valid locale-relative namespace path.
35    #[error("invalid namespace '{namespace}': {details}")]
36    InvalidNamespace {
37        namespace: String,
38        details: NamespacePathError,
39    },
40}
41
42/// Errors produced while discovering sparse resource plans from an assets tree.
43#[derive(Debug, thiserror::Error)]
44pub enum SparseAssetResourcePlanError {
45    /// The locale assets root could not be read.
46    #[error("Failed to read i18n directory at {path:?}: {source}")]
47    ReadAssetsRoot {
48        /// Assets root path.
49        path: PathBuf,
50        /// Filesystem error details.
51        source: std::io::Error,
52    },
53    /// A directory entry under the locale assets root could not be read.
54    #[error("Failed to read directory entry in {path:?}: {source}")]
55    ReadAssetsRootEntry {
56        /// Parent directory path.
57        path: PathBuf,
58        /// Filesystem error details.
59        source: std::io::Error,
60    },
61    /// A namespace directory could not be read.
62    #[error("Failed to read namespace directory {path:?}: {source}")]
63    ReadNamespaceDirectory {
64        /// Namespace directory path.
65        path: PathBuf,
66        /// Filesystem error details.
67        source: std::io::Error,
68    },
69    /// A namespace directory entry could not be read.
70    #[error("Failed to read directory entry in {path:?}: {source}")]
71    ReadNamespaceDirectoryEntry {
72        /// Parent directory path.
73        path: PathBuf,
74        /// Filesystem error details.
75        source: std::io::Error,
76    },
77    /// A locale directory name is not UTF-8.
78    #[error("Locale directory {path:?} contains a non-UTF-8 name")]
79    NonUtf8LocaleDirectory {
80        /// Locale directory path.
81        path: PathBuf,
82    },
83    /// A locale directory is not a valid canonical BCP-47 language identifier.
84    #[error("{}", format_locale_directory_error(raw_name, path, details))]
85    InvalidLocaleDirectory {
86        /// Raw directory name.
87        raw_name: String,
88        /// Locale directory path.
89        path: PathBuf,
90        /// Language parsing details.
91        details: CanonicalLanguageIdentifierError,
92    },
93    /// A namespace path could not be made relative to the namespace root.
94    #[error("Failed to derive namespace for asset {path:?} relative to {root:?}: {source}")]
95    NamespaceRelativePath {
96        /// FTL asset path.
97        path: PathBuf,
98        /// Namespace root path.
99        root: PathBuf,
100        /// Relative path error details.
101        source: std::path::StripPrefixError,
102    },
103    /// A namespace path contains a non-UTF-8 component.
104    #[error("Namespace path {path:?} contains non-UTF-8 components")]
105    NonUtf8NamespacePath {
106        /// Namespace path without the `.ftl` extension.
107        path: PathBuf,
108    },
109    /// A discovered namespace is not a canonical namespace path.
110    #[error("Discovered invalid namespace '{namespace}' in assets for crate '{domain}': {details}")]
111    InvalidNamespace {
112        /// Discovered namespace path.
113        namespace: String,
114        /// Module domain.
115        domain: String,
116        /// Namespace validation details.
117        details: NamespacePathError,
118    },
119}
120
121fn format_locale_directory_error(
122    raw_name: &str,
123    path: &Path,
124    details: &CanonicalLanguageIdentifierError,
125) -> String {
126    match details {
127        CanonicalLanguageIdentifierError::Invalid { source, .. } => format!(
128            "Locale directory '{raw_name}' under \"{}\" is not a valid BCP-47 identifier: {source}",
129            path.display()
130        ),
131        CanonicalLanguageIdentifierError::IcuInvalid { details, .. } => format!(
132            "Locale directory '{raw_name}' under \"{}\" could not be parsed as an ICU locale: {details}",
133            path.display()
134        ),
135        CanonicalLanguageIdentifierError::NonCanonical { canonical, .. } => format!(
136            "Locale directory '{raw_name}' under \"{}\" must use canonical BCP-47 form '{canonical}'",
137            path.display()
138        ),
139    }
140}