Skip to content

Commit

Permalink
map on text
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyan-dfinity committed Oct 20, 2022
1 parent 593dc2f commit 8ef95b4
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,18 @@ We also provide some built-in functions:
* output(path, content): append text content to file path.
* wasm_profiling(path): load Wasm module, instrument the code and store as a blob value. Calling profiled canister binds the cost to variable `__cost_{id}` or `__cost__`.
* flamegraph(canister_id, title, filename): generate flamegraph for the last update call to canister_id, with title and write to `{filename}.svg`.
* concat(e1, e2): concatenate two vec/record/text together.
* add/sub/mul/div(e1, e2): addition/subtraction/multiplication/division of two integer numbers.

## Object methods

For `vec` or `record` value, we provide some built-in methods for value transformation:
For `vec`, `record` or `text` value, we provide some built-in methods for value transformation:
* v.map(func): transform each item `v[i]` with `func(v[i])`.
* v.filter(func): filter out item `v[i]` if `func(v[i])` returns `false` or has an error.
* v.fold(init, func): combine all items in `v` by repeatedly apply `func(...func(func(init, v[0]), v[1])..., v[n-1])`.

For `record` value, `v[i]` is represented as `record { key; value }` sorted by field id.
for `text` value, `v[i]` is represented as a `text` value containing a single character.

## Examples

Expand Down
6 changes: 6 additions & 0 deletions examples/func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ function f7(acc, x) { let _ = concat(acc, vec{x[1]}) };
assert z.filter(f6).map(f5) == record { 1; 2 = 3; 4 };
assert z.filter(f6).map(f5).fold(vec{}, f7) == vec {1;3;4};

let s = "abcdef";
function f8(x) { let _ = stringify(" ", x) };
function f9(acc, x) { let _ = add(acc, 1) };
assert s.map(f8) == " a b c d e f";
assert s.map(f8).fold(0, f9) == 12;

34 changes: 31 additions & 3 deletions src/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ pub fn project(helper: &MyHelper, value: IDLValue, path: Vec<Selector>) -> Resul
let vs = from_fields(fs);
result = fold(helper, init, vs, &func)?;
}
(IDLValue::Text(s), Selector::Map(func)) => {
let vs = from_text(s);
let res = map(helper, vs, &func)?;
result = IDLValue::Text(to_text(res)?);
}
(IDLValue::Text(s), Selector::Filter(func)) => {
let vs = from_text(s);
let res = filter(helper, vs, &func)?;
result = IDLValue::Text(to_text(res)?);
}
(IDLValue::Text(s), Selector::Fold(init, func)) => {
let vs = from_text(s);
result = fold(helper, init, vs, &func)?;
}
(IDLValue::Record(fs), field @ (Selector::Index(_) | Selector::Field(_))) => {
let id = field.to_label();
if let Some(v) = fs.into_iter().find(|f| f.id == id) {
Expand Down Expand Up @@ -107,7 +121,21 @@ fn from_fields(fs: Vec<IDLField>) -> Vec<IDLValue> {
})
.collect()
}

fn from_text(s: String) -> Vec<IDLValue> {
s.chars().map(|c| IDLValue::Text(c.to_string())).collect()
}
fn to_text(from: Vec<IDLValue>) -> Result<String> {
use std::fmt::Write;
let mut res = String::with_capacity(from.len());
for v in from.into_iter() {
if let IDLValue::Text(s) = v {
write!(&mut res, "{}", s)?;
} else {
return Err(anyhow!("expect function to return text"));
}
}
Ok(res)
}
fn to_field(from: Vec<IDLValue>) -> Result<Vec<IDLField>> {
let mut fs = Vec::with_capacity(from.len());
for v in from.into_iter() {
Expand All @@ -126,9 +154,9 @@ fn to_field(from: Vec<IDLValue>) -> Result<Vec<IDLField>> {
val: val.clone(),
})
}
_ => return Err(anyhow!("map doesn't return record {{ key; value }}")),
_ => return Err(anyhow!("expect function to return record {{ key; value }}")),
},
_ => return Err(anyhow!("map doesn't return record {{ key; value }}")),
_ => return Err(anyhow!("expect function to return record {{ key; value }}")),
}
}
fs.sort_unstable_by_key(|IDLField { id, .. }| id.get_id());
Expand Down

0 comments on commit 8ef95b4

Please sign in to comment.