spin_manifest/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Configuration of an application for the Spin runtime.

#![deny(missing_docs)]

pub mod compat;
pub mod error;
pub mod normalize;
pub mod schema;

use std::path::Path;

use schema::v2::AppManifest;

pub use error::Error;

/// Parses a V1 or V2 app manifest file into a [`AppManifest`].
pub fn manifest_from_file(path: impl AsRef<Path>) -> Result<AppManifest, Error> {
    let manifest_str = std::fs::read_to_string(path)?;
    manifest_from_str(&manifest_str)
}

/// Parses a V1 or V2 app manifest into a [`AppManifest`].
pub fn manifest_from_str(v1_or_v2_toml: &str) -> Result<AppManifest, Error> {
    // TODO: would it be faster to parse into a toml::Table rather than parse twice?
    match ManifestVersion::detect(v1_or_v2_toml)? {
        ManifestVersion::V1 => {
            let deserialized_v1 = toml::from_str(v1_or_v2_toml)?;
            compat::v1_to_v2_app(deserialized_v1)
        }
        ManifestVersion::V2 => Ok(toml::from_str(v1_or_v2_toml)?),
    }
}

/// A Spin manifest schema version.
#[derive(Debug, PartialEq)]
pub enum ManifestVersion {
    /// Spin manifest schema version 1.
    V1,
    /// Spin manifest schema version 2.
    V2,
}

impl ManifestVersion {
    /// Detects the Spin manifest schema version of the given TOML content.
    pub fn detect(s: &str) -> Result<Self, Error> {
        let schema::VersionProbe {
            spin_manifest_version,
        } = toml::from_str(s)?;
        if spin_manifest_version.as_str() == Some("1") {
            Ok(Self::V1)
        } else if spin_manifest_version.as_integer() == Some(2) {
            Ok(Self::V2)
        } else {
            Err(Error::InvalidVersion(spin_manifest_version.to_string()))
        }
    }
}