Skip to content

Commit

Permalink
feat(law): implements object to uri mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
amimart committed Mar 23, 2023
1 parent 3ec96b2 commit 06df729
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion contracts/cw-law-stone/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rpath = false
cosmwasm-schema.workspace = true
cosmwasm-std.workspace = true
cosmwasm-storage.workspace = true
serde-json-wasm.workspace = true
cw-storage = { path = "../cw-storage" }
cw-storage-plus.workspace = true
cw-utils.worksapce = true
Expand All @@ -39,7 +40,7 @@ schemars.workspace = true
serde.workspace = true
thiserror.workspace = true
url = "2.3.1"
serde-json-wasm.workspace = true
form_urlencoded = "1.1.0"

[dev-dependencies]
cw-multi-test.workspace = true
Expand Down
71 changes: 54 additions & 17 deletions contracts/cw-law-stone/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::borrow::Cow;
use std::collections::HashMap;
use cosmwasm_std::Binary;
use cosmwasm_std::{Binary, StdError};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use cw_storage_plus::{Item, Map};
use url::Url;
use crate::ContractError;
use crate::ContractError::NotImplemented;
use crate::error::UriError;
use crate::ContractError;
use cw_storage::msg::QueryMsg as StorageQuery;
use cw_storage::msg::QueryMsg;
use cw_storage_plus::{Item, Map};
use url::Url;

/// State to store context during contract instantiation
pub const INSTANTIATE_CONTEXT: Item<'_, (String, Binary)> = Item::new("instantiate");
Expand All @@ -26,38 +25,77 @@ pub struct Object {

impl Object {
const COSMWASM_SCHEME: &'static str = "cosmwasm";
const COSMWASM_PATH_KEY: &'static str = "cw-storage";
}

impl TryFrom<Url> for Object {
type Error = UriError;

fn try_from(value: Url) -> Result<Self, UriError> {
if value.scheme() != Object::COSMWASM_SCHEME {
return Err(UriError::WrongScheme { scheme: value.scheme().to_string(), wanted: vec![Object::COSMWASM_SCHEME.to_string()] })
return Err(UriError::WrongScheme {
scheme: value.scheme().to_string(),
wanted: vec![Object::COSMWASM_SCHEME.to_string()],
});
}

let path = value.path().to_string();
let paths = path.split(":").collect::<Vec<&str>>();
if paths.len() == 0 || paths.len() > 2 {
return Err(UriError::IncompatiblePath)
return Err(UriError::IncompatiblePath);
}
let storage_address = paths.last().ok_or(UriError::IncompatiblePath)?.to_string();

let queries = value.query_pairs().into_owned().collect::<HashMap<String, String>>();
let queries = value
.query_pairs()
.into_owned()
.collect::<HashMap<String, String>>();

if let Some(query) = queries.get("query") {
let json: QueryMsg = serde_json_wasm::from_str(query.as_str())?;

return match json {
QueryMsg::ObjectData { id: object_id } => Ok(Object { object_id, storage_address }),
_ => Err(UriError::IncompatibleQuery)
}
QueryMsg::ObjectData { id: object_id } => Ok(Object {
object_id,
storage_address,
}),
_ => Err(UriError::IncompatibleQuery),
};
}

Err(UriError::MissingQueryKey)
}
}

impl TryInto<Url> for Object {
type Error = ContractError;

fn try_into(self) -> Result<Url, Self::Error> {
let raw = [
Object::COSMWASM_SCHEME,
":cw-storage:",
self.storage_address.as_str(),
"?",
form_urlencoded::Serializer::new(String::new())
.append_pair(
"query",
serde_json_wasm::to_string(&StorageQuery::ObjectData { id: self.object_id })
.map_err(|e| {
ContractError::Std(StdError::serialize_err("StorageQuery", e))
})?
.as_str(),
)
.finish()
.as_str(),
]
.join("");

Url::parse(&raw).map_err(|e| ContractError::DependencyUri {
uri: raw,
error: UriError::Parse(e),
})
}
}

pub const PROGRAM: Item<'_, Object> = Item::new("program");

pub const DEPENDENCIES: Map<'_, &str, Object> = Map::new("dependencies");
Expand Down Expand Up @@ -118,12 +156,11 @@ mod tests {

if let Some(err) = case.1 {
assert_eq!(err.to_string(), result.unwrap_err().to_string())
}
else if let Some(o) = case.2 {
} else if let Some(o) = case.2 {
assert_eq!(o, result.unwrap())
}
}
Err(_) => panic!("no error should be thrown")
Err(_) => panic!("no error should be thrown"),
}
}
}
Expand Down

0 comments on commit 06df729

Please sign in to comment.