Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Demo Gen Functions #671

Merged
merged 27 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8b42fca
Starting on the base attribute
ambiguousname Sep 3, 2024
80318f4
Merge branch 'main' into custom-demo-funcs
ambiguousname Sep 11, 2024
2a54aa0
Merge branch 'main' into custom-demo-funcs
ambiguousname Sep 11, 2024
85154d3
Starting on custom function logic
ambiguousname Sep 11, 2024
03a4438
Draft custom function setup
ambiguousname Sep 23, 2024
a7f7939
Fixing compiler bugs
ambiguousname Sep 23, 2024
0fad226
Updating errors and add reading custom_func
ambiguousname Sep 23, 2024
1697912
Custom functions now mostly outputting
ambiguousname Sep 23, 2024
d5bc004
TODO
ambiguousname Sep 23, 2024
1b2da1e
Evaluate function, then update it if it's custom
ambiguousname Sep 24, 2024
bca03e3
Formatting
ambiguousname Sep 24, 2024
cecdaf7
Update snapshots
ambiguousname Sep 24, 2024
4e47534
Fix export/import
ambiguousname Sep 24, 2024
caa03b6
Trying to fix root generation
ambiguousname Sep 24, 2024
536ce82
Rename custom functions in imports to avoid namespace errors
ambiguousname Sep 24, 2024
1d3d0e6
Formatting
ambiguousname Sep 24, 2024
b0e08c7
Give access to library for custom functions
ambiguousname Sep 25, 2024
25e0c0d
Adding test
ambiguousname Sep 25, 2024
5627015
Completely re-writing how custom funcs work
ambiguousname Sep 25, 2024
503f3b6
Fixing custom func usage away from Rust
ambiguousname Sep 25, 2024
6dbc28e
Formatting
ambiguousname Sep 25, 2024
d202937
Fix generation issues
ambiguousname Sep 25, 2024
7d9a5d4
Adding documentation
ambiguousname Sep 29, 2024
2e334e3
Update attrs.rs
ambiguousname Sep 29, 2024
2071bca
Formatting
ambiguousname Sep 29, 2024
db6919f
Trying to add some clarity to custom function definition
ambiguousname Sep 30, 2024
08951f5
Formatting
ambiguousname Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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