summaryrefslogtreecommitdiffstats
path: root/third_party/rust/fluent-testing/src/scenarios/structs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/fluent-testing/src/scenarios/structs.rs')
-rw-r--r--third_party/rust/fluent-testing/src/scenarios/structs.rs291
1 files changed, 291 insertions, 0 deletions
diff --git a/third_party/rust/fluent-testing/src/scenarios/structs.rs b/third_party/rust/fluent-testing/src/scenarios/structs.rs
new file mode 100644
index 0000000000..7ba2551c13
--- /dev/null
+++ b/third_party/rust/fluent-testing/src/scenarios/structs.rs
@@ -0,0 +1,291 @@
+use fluent_fallback::types::ResourceId;
+
+pub struct FileSource {
+ pub name: String,
+ pub locales: Vec<String>,
+ pub path_scheme: String,
+}
+
+impl Default for FileSource {
+ fn default() -> Self {
+ Self {
+ name: "default".to_string(),
+ path_scheme: "{locale}/".to_string(),
+ locales: vec!["en-US".to_string()],
+ }
+ }
+}
+
+impl FileSource {
+ pub fn new<S: ToString>(name: S, path_scheme: S, locales: Vec<S>) -> Self {
+ Self {
+ name: name.to_string(),
+ path_scheme: path_scheme.to_string(),
+ locales: locales
+ .iter()
+ .map(|l| l.to_string().parse().unwrap())
+ .collect(),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct L10nAttribute {
+ pub name: String,
+ pub value: String,
+}
+
+impl L10nAttribute {
+ pub fn new<S: ToString>(name: S, value: S) -> Self {
+ Self {
+ name: name.to_string(),
+ value: value.to_string(),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct L10nMessage {
+ pub value: Option<String>,
+ pub attributes: Option<Vec<L10nAttribute>>,
+}
+
+impl L10nMessage {
+ pub fn new(value: Option<&str>, attributes: Option<Vec<L10nAttribute>>) -> Self {
+ Self {
+ value: value.map(|v| v.to_string()),
+ attributes,
+ }
+ }
+}
+
+impl From<&str> for L10nMessage {
+ fn from(value: &str) -> Self {
+ Self {
+ value: Some(value.to_string()),
+ attributes: None,
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct L10nArgument {
+ pub id: String,
+ pub value: String,
+}
+
+impl L10nArgument {
+ pub fn new<S: ToString>(id: S, value: S) -> Self {
+ Self {
+ id: id.to_string(),
+ value: value.to_string(),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct L10nKey {
+ pub id: String,
+ pub args: Option<Vec<L10nArgument>>,
+}
+
+impl L10nKey {
+ pub fn new<S: ToString>(id: S, args: Option<Vec<L10nArgument>>) -> Self {
+ Self {
+ id: id.to_string(),
+ args,
+ }
+ }
+}
+
+impl From<&str> for L10nKey {
+ fn from(input: &str) -> Self {
+ Self {
+ id: input.to_string(),
+ args: None,
+ }
+ }
+}
+
+#[derive(Clone, Copy, Debug)]
+pub enum ExceptionalContext {
+ /// There is no exceptional context for this query (happy path).
+ None,
+ /// A value is missing from a resource and should cause a fallback.
+ ValueMissingFromResource,
+ /// A value is missing from all resources in all locales.
+ ValueMissingFromAllResources,
+ /// An optional resource is missing from the top locale.
+ OptionalResourceMissingFromLocale,
+ /// An optional resource is missing from all locales.
+ OptionalResourceMissingFromAllLocales,
+ /// A required resource is missing from the top locale.
+ RequiredResourceMissingFromLocale,
+ /// A required resource is missing from all locales.
+ RequiredResourceMissingFromAllLocales,
+}
+
+impl ExceptionalContext {
+ /// This is a query for a value in a missing required resource.
+ pub fn missing_required_resource(self) -> bool {
+ matches!(
+ self,
+ Self::RequiredResourceMissingFromLocale | Self::RequiredResourceMissingFromAllLocales,
+ )
+ }
+
+ /// This query should cause a format error to be appended to the errors Vec.
+ pub fn causes_reported_format_error(self) -> bool {
+ matches!(
+ self,
+ Self::ValueMissingFromResource
+ | Self::ValueMissingFromAllResources
+ | Self::OptionalResourceMissingFromLocale
+ | Self::OptionalResourceMissingFromAllLocales
+ | Self::RequiredResourceMissingFromAllLocales,
+ )
+ }
+
+ /// This query should cause a failed value lookup.
+ pub fn causes_failed_value_lookup(self) -> bool {
+ matches!(
+ self,
+ Self::ValueMissingFromAllResources
+ | Self::OptionalResourceMissingFromAllLocales
+ | Self::RequiredResourceMissingFromAllLocales,
+ )
+ }
+
+ /// This query should result in no bundles being generated.
+ pub fn blocks_bundle_generation(self) -> bool {
+ matches!(self, Self::RequiredResourceMissingFromAllLocales,)
+ }
+}
+
+#[derive(Debug)]
+pub struct Query {
+ pub input: L10nKey,
+ pub output: Option<L10nMessage>,
+ pub exceptional_context: ExceptionalContext,
+}
+
+impl Query {
+ pub fn new<K: Into<L10nKey>>(input: K, output: Option<L10nMessage>) -> Self {
+ Self {
+ input: input.into(),
+ output,
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+impl From<(&str, &str)> for Query {
+ fn from(i: (&str, &str)) -> Self {
+ Self {
+ input: i.0.into(),
+ output: Some(i.1.into()),
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+impl From<(&str, &str, ExceptionalContext)> for Query {
+ fn from(i: (&str, &str, ExceptionalContext)) -> Self {
+ Self {
+ input: i.0.into(),
+ output: Some(i.1.into()),
+ exceptional_context: i.2,
+ }
+ }
+}
+
+impl From<(&str, L10nMessage)> for Query {
+ fn from(i: (&str, L10nMessage)) -> Self {
+ Self {
+ input: i.0.into(),
+ output: Some(i.1),
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+impl From<(L10nKey, L10nMessage)> for Query {
+ fn from(i: (L10nKey, L10nMessage)) -> Self {
+ Self {
+ input: i.0,
+ output: Some(i.1),
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+impl From<&str> for Query {
+ fn from(i: &str) -> Self {
+ Self {
+ input: i.into(),
+ output: None,
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+impl From<L10nKey> for Query {
+ fn from(key: L10nKey) -> Self {
+ Self {
+ input: key,
+ output: None,
+ exceptional_context: ExceptionalContext::None,
+ }
+ }
+}
+
+pub struct Queries(pub Vec<Query>);
+
+impl From<Vec<&str>> for Queries {
+ fn from(input: Vec<&str>) -> Self {
+ Self(input.into_iter().map(|q| q.into()).collect())
+ }
+}
+
+impl From<Vec<(&str, &str)>> for Queries {
+ fn from(input: Vec<(&str, &str)>) -> Self {
+ Self(input.into_iter().map(|q| q.into()).collect())
+ }
+}
+
+impl std::ops::Deref for Queries {
+ type Target = Vec<Query>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+pub struct Scenario {
+ pub name: String,
+ pub file_sources: Vec<FileSource>,
+ pub locales: Vec<String>,
+ pub res_ids: Vec<ResourceId>,
+ pub queries: Queries,
+}
+
+impl Scenario {
+ pub fn new<S: ToString, R: Into<ResourceId>, Q: Into<Queries>>(
+ name: S,
+ file_sources: Vec<FileSource>,
+ locales: Vec<S>,
+ res_ids: Vec<R>,
+ queries: Q,
+ ) -> Self {
+ Self {
+ name: name.to_string(),
+ file_sources,
+ locales: locales
+ .into_iter()
+ .map(|l| l.to_string().parse().unwrap())
+ .collect(),
+ res_ids: res_ids.into_iter().map(|id| id.into()).collect(),
+ queries: queries.into(),
+ }
+ }
+}