-
Notifications
You must be signed in to change notification settings - Fork 229
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added first cut design of Intermediate Representation module
- Loading branch information
Showing
6 changed files
with
246 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
* */ | ||
|
||
//! Not complete yet | ||
//! This is where the error definitions can go | ||
//! TODO: Implement proper error handling, this would include defining the error enum, | ||
//! impl std::error::Error using `thiserror` and ensuring all errors are handled appropriately | ||
#[derive(Debug, thiserror::Error)] | ||
pub enum FMLError { | ||
#[error("IO error: {0}")] | ||
IOError(#[from] std::io::Error), | ||
#[error("JSON Error: {0}")] | ||
JSONError(#[from] serde_json::Error), | ||
#[error("Invalid path: {0}")] | ||
InvalidPath(String), | ||
#[error("Internal error: {0}")] | ||
InternalError(&'static str), | ||
} | ||
|
||
pub type Result<T, E = FMLError> = std::result::Result<T, E>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
pub(crate) mod ir; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
use crate::ir::{EnumDef, FeatureDef, FeatureManifest, PropDef, TypeRef, VariantDef}; | ||
use serde_json::json; | ||
|
||
pub(crate) fn get_simple_nimbus_validation_feature() -> FeatureManifest { | ||
FeatureManifest { | ||
enum_defs: vec![], | ||
obj_defs: vec![], | ||
feature_defs: vec![FeatureDef::new( | ||
"nimbus-validation", | ||
"A simple validation feature", | ||
vec![ | ||
PropDef { | ||
name: "enabled".into(), | ||
doc: "An example boolean property".into(), | ||
typ: TypeRef::Boolean, | ||
default: json!(true), | ||
}, | ||
PropDef { | ||
name: "row-count".into(), | ||
doc: "An example integer property".into(), | ||
typ: TypeRef::Boolean, | ||
default: json!(2), | ||
}, | ||
PropDef { | ||
name: "deeplink".into(), | ||
doc: "An example string property".into(), | ||
typ: TypeRef::String, | ||
default: json!("deeplink://settings"), | ||
}, | ||
], | ||
None, | ||
)], | ||
} | ||
} | ||
|
||
pub(crate) fn get_simple_homescreen_feature() -> FeatureManifest { | ||
FeatureManifest { | ||
enum_defs: vec![EnumDef { | ||
name: "SectionId".into(), | ||
doc: "The sections of the homescreen".into(), | ||
variants: vec![ | ||
VariantDef::new("top-sites", "The original frecency sorted sites"), | ||
VariantDef::new("jump-back-in", "Jump back in section"), | ||
VariantDef::new("recently-saved", "Tabs that have been bookmarked recently"), | ||
], | ||
}], | ||
obj_defs: vec![], | ||
feature_defs: vec![FeatureDef::new( | ||
"homescreen", | ||
"Represents the homescreen feature", | ||
vec![PropDef { | ||
name: "sections-enabled".into(), | ||
doc: "A map of booleans".into(), | ||
typ: TypeRef::EnumMap( | ||
Box::new(TypeRef::Enum("SectionId".into())), | ||
Box::new(TypeRef::String), | ||
), | ||
default: json!({ | ||
"top-sites": true, | ||
"jump-back-in": false, | ||
"recently-saved": false, | ||
}), | ||
}], | ||
None, | ||
)], | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
use serde::{Deserialize, Serialize}; | ||
use serde_json::Value; | ||
|
||
/// The `TypeRef` enum defines a reference to a type. | ||
/// | ||
/// Other types will be defined in terms of these enum values. | ||
/// | ||
/// They represent the types available via the current `Variables` API— | ||
/// some primitives and structural types— and can be represented by | ||
/// Kotlin, Swift and JSON Schema. | ||
/// | ||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] | ||
pub(crate) enum TypeRef { | ||
// Current primitives. | ||
String, | ||
Int, | ||
Boolean, | ||
|
||
// Strings can be coerced into a few types. | ||
// The types here will require the app's bundle or context to look up the final value. | ||
// They will likely have | ||
BundleText(String), | ||
BundleImage(String), | ||
|
||
Enum(String), | ||
// JSON objects can represent a data class. | ||
Object(String), | ||
|
||
// JSON objects can also represent a `Map<String, V>` or a `Map` with | ||
// keys that can be derived from a string. | ||
StringMap(Box<TypeRef>), | ||
// We can coerce the String keys into Enums, so this repesents that. | ||
EnumMap(Box<TypeRef>, Box<TypeRef>), | ||
|
||
List(Box<TypeRef>), | ||
Option(Box<TypeRef>), | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct FeatureManifest { | ||
pub enum_defs: Vec<EnumDef>, | ||
pub obj_defs: Vec<ObjectDef>, | ||
pub feature_defs: Vec<FeatureDef>, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct FeatureDef { | ||
name: String, | ||
doc: String, | ||
props: Vec<PropDef>, | ||
default: Option<Literal>, | ||
} | ||
impl FeatureDef { | ||
pub fn new(name: &str, doc: &str, props: Vec<PropDef>, default: Option<Literal>) -> Self { | ||
Self { | ||
name: name.into(), | ||
doc: doc.into(), | ||
props, | ||
default, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct EnumDef { | ||
pub name: String, | ||
pub doc: String, | ||
pub variants: Vec<VariantDef>, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct FromStringDef { | ||
pub name: String, | ||
pub doc: String, | ||
pub variants: Vec<VariantDef>, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub struct VariantDef { | ||
name: String, | ||
doc: String, | ||
} | ||
impl VariantDef { | ||
pub fn new(name: &str, doc: &str) -> Self { | ||
Self { | ||
name: name.into(), | ||
doc: doc.into(), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct ObjectDef { | ||
name: String, | ||
doc: String, | ||
props: Vec<PropDef>, | ||
} | ||
impl ObjectDef { | ||
pub fn new(name: &str, doc: &str, props: Vec<PropDef>) -> Self { | ||
Self { | ||
name: name.into(), | ||
doc: doc.into(), | ||
props, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||
pub(crate) struct PropDef { | ||
pub name: String, | ||
pub doc: String, | ||
pub typ: TypeRef, | ||
pub default: Literal, | ||
} | ||
|
||
type Literal = Value; | ||
|
||
#[cfg(test)] | ||
mod unit_tests { | ||
use super::*; | ||
use crate::error::Result; | ||
use crate::fixtures::ir; | ||
|
||
#[test] | ||
fn can_ir_represent_smoke_test() -> Result<()> { | ||
let m1 = ir::get_simple_homescreen_feature(); | ||
let string = serde_json::to_string(&m1)?; | ||
let m2: FeatureManifest = serde_json::from_str(&string)?; | ||
|
||
assert_eq!(m1, m2); | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters