use super::dependency::{Dependency, StaticDependency};
use cosmwasm_std::{Empty, Querier, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery};
use cw_storage_plus::Item;
use serde::{Deserialize, Serialize};
pub const MODULE: Item<ModuleData> = Item::new("module_data");
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ModuleData {
pub module: String,
pub version: String,
pub dependencies: Vec<Dependency>,
pub metadata: Option<String>,
}
pub fn get_module_data(store: &dyn Storage) -> StdResult<ModuleData> {
MODULE.load(store).map_err(Into::into)
}
pub fn set_module_data<T: Into<String>, U: Into<String>, M: Into<String>>(
store: &mut dyn Storage,
name: T,
version: U,
dependencies: &[StaticDependency],
metadata: Option<M>,
) -> StdResult<()> {
let val = ModuleData {
module: name.into(),
version: version.into(),
dependencies: dependencies.iter().map(Into::into).collect(),
metadata: metadata.map(Into::into),
};
MODULE.save(store, &val).map_err(Into::into)
}
pub fn migrate_module_data(
store: &mut dyn Storage,
name: &str,
version: &str,
metadata: Option<String>,
) -> StdResult<()> {
let old_module_data = MODULE.may_load(store)?;
let val = old_module_data.map_or(
ModuleData {
module: name.into(),
version: version.into(),
dependencies: vec![],
metadata: None,
},
|data| ModuleData {
module: name.into(),
version: version.into(),
dependencies: data.dependencies,
metadata: metadata.or(data.metadata),
},
);
MODULE.save(store, &val).map_err(Into::into)
}
pub fn query_module_data<Q: Querier, T: Into<String>>(
querier: &Q,
contract_addr: T,
) -> StdResult<ModuleData> {
let req = QueryRequest::Wasm(WasmQuery::Raw {
contract_addr: contract_addr.into(),
key: MODULE.as_slice().into(),
});
QuerierWrapper::<Empty>::new(querier)
.query(&req)
.map_err(Into::into)
}
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::testing::MockStorage;
#[test]
fn get_and_set_work() {
let mut store = MockStorage::new();
assert!(get_module_data(&store).is_err());
let contract_name = "crate:cw20-base";
let contract_version = "0.2.0";
let metadata = Some("https://example.com");
const REQUIREMENT: [&str; 1] = [">1"];
const DEPENDENCIES: &[StaticDependency; 1] = &[StaticDependency {
id: "abstact::dex",
version_req: &REQUIREMENT,
}];
set_module_data(
&mut store,
contract_name,
contract_version,
DEPENDENCIES,
metadata,
)
.unwrap();
let loaded = get_module_data(&store).unwrap();
let expected = ModuleData {
module: contract_name.to_string(),
version: contract_version.to_string(),
dependencies: DEPENDENCIES.iter().map(Into::into).collect(),
metadata: metadata.map(Into::into),
};
assert_eq!(expected, loaded);
}
}