(agent: &Agent, path: StatePath)
| 321 | res.first().map(|(a, _)| *a) |
| 322 | } |
| 323 | async fn fetch_state_path_(agent: &Agent, path: StatePath) -> anyhow::Result<IDLValue> { |
| 324 | use ic_agent::{hash_tree::SubtreeLookupResult, lookup_value}; |
| 325 | let effective_id = path.effective_id.unwrap(); |
| 326 | let cert = match path.kind { |
| 327 | StateKind::Subnet => { |
| 328 | agent |
| 329 | .read_subnet_state_raw(vec![path.path.clone()], effective_id) |
| 330 | .await? |
| 331 | } |
| 332 | StateKind::Canister => { |
| 333 | agent |
| 334 | .read_state_raw(vec![path.path.clone()], effective_id) |
| 335 | .await? |
| 336 | } |
| 337 | }; |
| 338 | if matches!(path.result, StateType::Subtree) { |
| 339 | let tree = match cert.tree.lookup_subtree(&path.path) { |
| 340 | SubtreeLookupResult::Found(t) => t, |
| 341 | SubtreeLookupResult::Absent => return Err(anyhow!("Subtree absent")), |
| 342 | SubtreeLookupResult::Unknown => return Err(anyhow!("Subtree unknown")), |
| 343 | }; |
| 344 | let paths = tree.list_paths(); |
| 345 | let ids: std::collections::HashSet<_> = paths |
| 346 | .iter() |
| 347 | .map(|p| Principal::from_slice(p[0].as_bytes())) |
| 348 | .collect(); |
| 349 | Ok(IDLValue::Vec( |
| 350 | ids.into_iter().map(IDLValue::Principal).collect(), |
| 351 | )) |
| 352 | } else { |
| 353 | let bytes = lookup_value(&cert, path.path).map(<[u8]>::to_vec)?; |
| 354 | Ok(match path.result { |
| 355 | StateType::Blob => IDLValue::Blob(bytes), |
| 356 | StateType::Text => IDLValue::Text(String::from_utf8(bytes)?), |
| 357 | StateType::Nat => { |
| 358 | let mut reader = std::io::Cursor::new(bytes); |
| 359 | let n = candid::Nat::decode(&mut reader)?; |
| 360 | IDLValue::Nat(n) |
| 361 | } |
| 362 | StateType::Controllers => { |
| 363 | let res = serde_cbor::from_slice::<Vec<Principal>>(&bytes)?; |
| 364 | IDLValue::Vec(res.into_iter().map(IDLValue::Principal).collect()) |
| 365 | } |
| 366 | StateType::Ranges => { |
| 367 | let res = serde_cbor::from_slice::<Vec<(Principal, Principal)>>(&bytes)?; |
| 368 | IDLValue::Vec( |
| 369 | res.into_iter() |
| 370 | .map(|(a, b)| { |
| 371 | IDLValue::Record(vec![ |
| 372 | IDLField { |
| 373 | id: Label::Id(0), |
| 374 | val: IDLValue::Principal(a), |
| 375 | }, |
| 376 | IDLField { |
| 377 | id: Label::Id(1), |
| 378 | val: IDLValue::Principal(b), |
| 379 | }, |
| 380 | ]) |
no test coverage detected