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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
//! Normalized, validated representation of the App Manifest.
//!
//! The versioned manifest structs are designed to be deserialized from YAML,
//! and so they contain various optional fields. They are not validated, and
//! may contain various invalid combinations of data. In contrast, these types
//! are structured to ensure validity, and are used internally by Holochain.
use holochain_zome_types::DnaModifiersOpt;
use super::error::{AppManifestError, AppManifestResult};
use crate::app::app_manifest::current::{DnaLocation, DnaVersionSpec};
use crate::prelude::AppRoleId;
use std::collections::HashMap;
/// Normalized, validated representation of the App Manifest.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AppManifestValidated {
/// Name of the App. This may be used as the installed_app_id.
pub(in crate::app) name: String,
/// The role descriptions that make up this app.
pub(in crate::app) roles: HashMap<AppRoleId, AppRoleManifestValidated>,
}
impl AppManifestValidated {
/// Constructor with internal consistency checks.
///
/// NB: never make this struct's fields public. This constructor should be
/// the only way to instantiate this type.
pub(in crate::app) fn new(
name: String,
roles: HashMap<AppRoleId, AppRoleManifestValidated>,
) -> AppManifestResult<Self> {
for (role_id, role) in roles.iter() {
if let AppRoleManifestValidated::Disabled { clone_limit, .. } = role {
if *clone_limit == 0 {
return Err(AppManifestError::InvalidStrategyDisabled(
role_id.to_owned(),
));
}
}
}
Ok(AppManifestValidated { name, roles })
}
}
/// Rules to determine if and how a Cell will be created for this Dna
#[allow(missing_docs)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AppRoleManifestValidated {
/// Always create a new Cell when installing this App
Create {
clone_limit: u32,
deferred: bool,
location: DnaLocation,
modifiers: DnaModifiersOpt,
version: Option<DnaVersionSpec>,
},
/// Always create a new Cell when installing the App,
/// and use a unique network seed to ensure a distinct DHT network
CreateClone {
clone_limit: u32,
deferred: bool,
location: DnaLocation,
modifiers: DnaModifiersOpt,
version: Option<DnaVersionSpec>,
},
/// Require that a Cell is already installed which matches the DNA version
/// spec, and which has an Agent that's associated with this App's agent
/// via DPKI. If no such Cell exists, *app installation fails*.
UseExisting {
clone_limit: u32,
deferred: bool,
version: DnaVersionSpec,
},
/// Try `UseExisting`, and if that fails, fallback to `Create`
CreateIfNotExists {
clone_limit: u32,
deferred: bool,
location: DnaLocation,
modifiers: DnaModifiersOpt,
version: DnaVersionSpec,
},
/// Disallow provisioning altogether. In this case, we expect
/// `clone_limit > 0`: otherwise, no cells will ever be created.
Disabled {
version: DnaVersionSpec,
clone_limit: u32,
},
}