Skip to content

Commit

Permalink
(Nimbus-FML) Added first cut design of Intermediate Representation mo…
Browse files Browse the repository at this point in the history
…dule (#4604) r=travis

* Added first cut design of Intermediate Representation module

* Rename ir to intermediate_representation and add hints for strings

* Add fixtures

* Add commands to load and save IR

* cargo clippy

* Cargo.lock
  • Loading branch information
jhugman committed Oct 22, 2021
1 parent a5613c6 commit 1dab6d7
Show file tree
Hide file tree
Showing 11 changed files with 477 additions and 30 deletions.
22 changes: 16 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions components/support/nimbus-fml/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ license = "MPL-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = "2.33"
anyhow = "1"
clap = {version = "2.33.0", features = ["yaml"]}
anyhow = "1.0.44"
serde_json = "1"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0.29"
50 changes: 50 additions & 0 deletions components/support/nimbus-fml/fixtures/simple_homescreen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"enum_defs": [
{
"name": "SectionId",
"doc": "The sections of the homescreen",
"variants": [
{
"name": "top-sites",
"doc": "The original frecency sorted sites"
},
{
"name": "jump-back-in",
"doc": "Jump back in section"
},
{
"name": "recently-saved",
"doc": "Tabs that have been bookmarked recently"
}
]
}
],
"obj_defs": [],
"hints": {},
"feature_defs": [
{
"name": "homescreen",
"doc": "Represents the homescreen feature",
"props": [
{
"name": "sections-enabled",
"doc": "A map of booleans",
"typ": {
"EnumMap": [
{
"Enum": "SectionId"
},
"String"
]
},
"default": {
"jump-back-in": false,
"recently-saved": false,
"top-sites": true
}
}
],
"default": null
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"enum_defs": [],
"obj_defs": [],
"hints": {},
"feature_defs": [
{
"name": "nimbus-validation",
"doc": "A simple validation feature",
"props": [
{
"name": "enabled",
"doc": "An example boolean property",
"typ": "Boolean",
"default": true
},
{
"name": "row-count",
"doc": "An example integer property",
"typ": "Boolean",
"default": 2
},
{
"name": "deeplink",
"doc": "An example string property",
"typ": "String",
"default": "deeplink://settings"
}
],
"default": null
}
]
}
37 changes: 37 additions & 0 deletions components/support/nimbus-fml/src/cli.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: nimbus-fml
version: "1.0"
author: nimbus-dev@mozilla.com
about: Tool for working with Nimbus Feature Manifests
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- verbose:
short: v
multiple: true
help: Sets the level of verbosity
subcommands:
- struct:
about: Generate the app code for configuring features
args:
- language:
short: l
long: language
value_name: LANGUAGE
possible_values: [ kotlin, swift, ir ]
- INPUT:
help: Sets the input file to use
required: true
index: 1
- ir:
help: The input file is intermediate representation. Useful for debugging FML.
long: ir
- output:
help: The output file
short: o
long: output
value_name: FILE
required: true
22 changes: 22 additions & 0 deletions components/support/nimbus-fml/src/error.rs
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>;
5 changes: 5 additions & 0 deletions components/support/nimbus-fml/src/fixtures.rs
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 intermediate_representation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* 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::intermediate_representation::{
EnumDef, FeatureDef, FeatureManifest, PropDef, TypeRef, VariantDef,
};
use serde_json::json;

pub(crate) fn get_simple_nimbus_validation_feature() -> FeatureManifest {
FeatureManifest {
enum_defs: Default::default(),
obj_defs: Default::default(),
hints: Default::default(),
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: Default::default(),
hints: Default::default(),
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,
)],
}
}

#[cfg(test)]
mod dump_to_file {
use std::path::PathBuf;

use crate::error::Result;

use super::*;

fn write(fm: &FeatureManifest, nm: &str) -> Result<()> {
let root = std::env::var("CARGO_MANIFEST_DIR")
.expect("Missing $CARGO_MANIFEST_DIR, cannot write fixtures files");
let fixtures_dir = "fixtures";
let path: PathBuf = [&root, fixtures_dir, nm].iter().collect();

let contents = serde_json::to_string_pretty(fm)?;

std::fs::write(path, contents)?;

Ok(())
}

#[test]
fn write_to_fixtures_dir() -> Result<()> {
write(&get_simple_homescreen_feature(), "simple_homescreen.json")?;
write(
&get_simple_nimbus_validation_feature(),
"simple_nimbus_validation.json",
)?;

Ok(())
}
}
Loading

0 comments on commit 1dab6d7

Please sign in to comment.