(helper: &MyHelper, value: IDLValue, path: Vec<Selector>)
| 31 | } |
| 32 | } |
| 33 | pub fn project(helper: &MyHelper, value: IDLValue, path: Vec<Selector>) -> Result<IDLValue> { |
| 34 | let mut result = value; |
| 35 | for head in path.into_iter() { |
| 36 | match (result, head) { |
| 37 | (IDLValue::Opt(opt), Selector::Option) => result = *opt, |
| 38 | (IDLValue::Blob(b), Selector::Index(e)) => { |
| 39 | let idx = as_u32(&e.eval(helper)?)?; |
| 40 | result = IDLValue::Nat8( |
| 41 | *b.get(idx as usize) |
| 42 | .ok_or_else(|| anyhow!("idx out of bound"))?, |
| 43 | ) |
| 44 | } |
| 45 | (IDLValue::Vec(mut vs), Selector::Index(e)) => { |
| 46 | let idx = as_u32(&e.eval(helper)?)? as usize; |
| 47 | if idx < vs.len() { |
| 48 | result = vs.swap_remove(idx); |
| 49 | } else { |
| 50 | return Err(anyhow!("{} out of bound {}", idx, vs.len())); |
| 51 | } |
| 52 | } |
| 53 | (IDLValue::Text(s), Selector::Index(e)) => { |
| 54 | let idx = as_u32(&e.eval(helper)?)? as usize; |
| 55 | if idx < s.len() { |
| 56 | result = IDLValue::Text(s.chars().nth(idx).unwrap().to_string()); |
| 57 | } else { |
| 58 | return Err(anyhow!("{} out of bound {}", idx, s.len())); |
| 59 | } |
| 60 | } |
| 61 | (IDLValue::Blob(b), Selector::Map(func)) => { |
| 62 | let vs = b.into_iter().map(IDLValue::Nat8).collect(); |
| 63 | result = IDLValue::Vec(map(helper, vs, &func)?); |
| 64 | } |
| 65 | (IDLValue::Vec(vs), Selector::Map(func)) => { |
| 66 | result = IDLValue::Vec(map(helper, vs, &func)?); |
| 67 | } |
| 68 | (IDLValue::Blob(b), Selector::Filter(func)) => { |
| 69 | let vs = b.into_iter().map(IDLValue::Nat8).collect(); |
| 70 | result = IDLValue::Vec(filter(helper, vs, &func)?); |
| 71 | } |
| 72 | (IDLValue::Vec(vs), Selector::Filter(func)) => { |
| 73 | result = IDLValue::Vec(filter(helper, vs, &func)?); |
| 74 | } |
| 75 | (IDLValue::Blob(b), Selector::Fold(init, func)) => { |
| 76 | let vs = b.into_iter().map(IDLValue::Nat8).collect(); |
| 77 | result = fold(helper, init, vs, &func)?; |
| 78 | } |
| 79 | (IDLValue::Vec(vs), Selector::Fold(init, func)) => { |
| 80 | result = fold(helper, init, vs, &func)?; |
| 81 | } |
| 82 | (IDLValue::Blob(b), Selector::Size) => { |
| 83 | result = IDLValue::Nat(b.len().into()); |
| 84 | } |
| 85 | (IDLValue::Vec(vs), Selector::Size) => { |
| 86 | result = IDLValue::Nat(vs.len().into()); |
| 87 | } |
| 88 | (IDLValue::Record(fs), Selector::Map(func)) => { |
| 89 | let vs = from_fields(fs); |
| 90 | let res = map(helper, vs, &func)?; |
no test coverage detected