verifier/
voyager.rs

1use camino::Utf8PathBuf;
2use scarb_metadata::{Metadata, PackageId};
3use serde::Deserialize;
4use std::{collections::HashMap, path::PathBuf};
5use thiserror::Error;
6
7pub type ContractMap = HashMap<String, Voyager>;
8
9#[allow(dead_code)]
10#[derive(Clone, Debug, Deserialize)]
11pub struct Voyager {
12    pub path: PathBuf,
13    pub address: Option<String>,
14}
15
16#[derive(Debug, Error)]
17pub enum Error {
18    #[error(transparent)]
19    Deserialization(#[from] serde_json::Error),
20}
21
22// Use this instead of metadata.runtime_manifest, because of:
23// https://docs.rs/scarb-metadata/latest/scarb_metadata/struct.Metadata.html#compatibility
24// > With very old Scarb versions (<0.5.0), this field may end up being
25// > empty path upon deserializing from scarb metadata call. In this
26// >  case, fall back to WorkspaceMetadata.manifest field value.
27// but I've actually got this in scarb 0.5.1, so...
28#[must_use]
29pub fn manifest_path(metadata: &Metadata) -> &Utf8PathBuf {
30    if metadata.runtime_manifest == Utf8PathBuf::new() {
31        &metadata.workspace.manifest_path
32    } else {
33        &metadata.runtime_manifest
34    }
35}
36
37/// # Errors
38///
39/// Will return `Err` if `tool.voyager` section can't be deserialized.
40pub fn tool_section(metadata: &Metadata) -> Result<HashMap<PackageId, ContractMap>, Error> {
41    let mut voyager: HashMap<PackageId, ContractMap> = HashMap::new();
42    for package in &metadata.packages {
43        if !metadata.workspace.members.contains(&package.id) {
44            continue;
45        }
46
47        if let Some(tool) = package.tool_metadata("voyager") {
48            let contracts =
49                serde_json::from_value::<ContractMap>(tool.clone()).map_err(Error::from)?;
50            voyager.insert(package.id.clone(), contracts);
51        }
52    }
53    Ok(voyager)
54}