Skip to content

Commit

Permalink
Custom Demo Gen Functions (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
ambiguousname authored Sep 30, 2024
1 parent 3a6e50c commit 32fd9ee
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 160 deletions.
32 changes: 30 additions & 2 deletions core/src/hir/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ pub struct DemoInfo {
/// `#[diplomat::demo(external)]` represents an item that we will not evaluate, and should be passed to the rendering engine to provide.
pub external: bool,

/// `#[diplomat::demo(custom_func = "/file/name/here.mjs")]` can be used above any `struct` definition in the bridge. The linked `.mjs` should contain a JS definition of functions that should be bundled with demo_gen's output.
///
/// We call these functions "custom functions", as they are JS functions that are not automagically generated by demo_gen, but rather included as part of its JS output in the `RenderInfo` object.
///
/// For more information on custom functions (and their use), see the relevant chapter in [the book](https://rust-diplomat.github.io/book/demo_gen/custom_functions.html).
///
/// Files are located relative to lib.rs.
///
pub custom_func: Option<String>,

/// `#[diplomat::demo(input(...))]` represents configuration options for anywhere we might expect user input.
pub input_cfg: DemoInputCFG,
}
Expand Down Expand Up @@ -405,11 +415,29 @@ impl Attrs {
}
})
.expect("Could not read input(...)");
} else if path_ident == "custom_func" {
let v = &attr.meta.require_name_value().unwrap().value;

if let syn::Expr::Lit(s) = v {
if let syn::Lit::Str(string) = &s.lit {
this.demo_attrs.custom_func = Some(string.value());
} else {
errors.push(LoweringError::Other(format!(
"#[diplomat::demo(custom_func={s:?}) must be a literal string."
)));
}
} else {
errors.push(LoweringError::Other(format!(
"#[diplomat::demo(custom_func={v:?}) must be a literal string."
)));
}
} else {
panic!("Unknown demo_attr: {path_ident:?}");
errors.push(LoweringError::Other(format!(
"Unknown demo_attr: {path_ident:?}"
)));
}
} else {
panic!("Unknown demo_attr: {path:?}");
errors.push(LoweringError::Other(format!("Unknown demo_attr: {path:?}")));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Method {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -100,6 +101,7 @@ Method {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand All @@ -125,6 +127,7 @@ Method {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -107,6 +108,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -151,6 +153,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand All @@ -173,6 +176,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -236,6 +240,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -294,6 +299,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -331,6 +337,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -369,6 +376,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand All @@ -391,6 +399,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down Expand Up @@ -436,6 +445,7 @@ TypeContext {
generate: false,
default_constructor: false,
external: false,
custom_func: None,
input_cfg: DemoInputCFG {
label: "",
default_value: "",
Expand Down
20 changes: 20 additions & 0 deletions example/demo_gen/custom_func/a.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { lib } from "./index.mjs";

export function multiplyPow10(power) {
let fixedDecimal = lib.FixedDecimal.new_(10);
fixedDecimal.multiplyPow10(power);
return fixedDecimal.toString();
}

export default {
"FixedDecimal.multiplyPow10": {
func: multiplyPow10,
funcName: "FixedDecimal.multiplyPow10",
parameters: [
{
name: "power",
type: "number"
}
]
}
};
20 changes: 20 additions & 0 deletions example/demo_gen/demo/a.mjs

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

98 changes: 51 additions & 47 deletions example/demo_gen/demo/index.mjs

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

6 changes: 5 additions & 1 deletion example/demo_gen/test/test-demo.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from "ava";
import { FixedDecimalDemo, FixedDecimalFormatterDemo } from "mini-icu4x-demo";
import { FixedDecimalDemo, FixedDecimalFormatterDemo, RenderInfo } from "mini-icu4x-demo";
import { FixedDecimalGroupingStrategy } from "mini-icu4x";


Expand All @@ -9,4 +9,8 @@ test("Test FixedDecimal", (t) => {

test("Test FixedDecimalFormatter", (t) => {
t.is(FixedDecimalFormatterDemo.formatWrite("en", FixedDecimalGroupingStrategy.Always, false, 1000), "1,000");
});

test("Custom Function", (t) => {
t.is(RenderInfo.termini["FixedDecimal.multiplyPow10"].func(3), "10000");
});
3 changes: 3 additions & 0 deletions example/src/fixed_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ pub mod ffi {

#[diplomat::opaque]
#[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
// Link to where other custom functions for this class can be found.
// Make sure any .mjs file export defaults an object that matches the `RenderTerminus.terminus` object in content.
#[diplomat::demo(custom_func = "../demo_gen/custom_func/a.mjs")]
pub struct FixedDecimal(pub fixed_decimal::FixedDecimal);

impl FixedDecimal {
Expand Down
Loading

0 comments on commit 32fd9ee

Please sign in to comment.