wip: move components functionality to Address

feat/type-attributes
Tomáš Mládek 2023-06-26 21:20:40 +02:00
parent c4de2eb252
commit 53000ca5d1
4 changed files with 73 additions and 45 deletions

33
Cargo.lock generated
View File

@ -3299,6 +3299,14 @@ dependencies = [
"walkdir",
]
[[package]]
name = "upend_wasm"
version = "0.1.0"
dependencies = [
"upend-base",
"wasm-bindgen",
]
[[package]]
name = "url"
version = "2.3.1"
@ -3347,6 +3355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.9",
"serde",
]
[[package]]
@ -3407,9 +3416,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.84"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -3417,16 +3426,16 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.84"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.15",
"wasm-bindgen-shared",
]
@ -3444,9 +3453,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.84"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -3454,22 +3463,22 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.84"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.15",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.84"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "web-sys"

View File

@ -30,7 +30,7 @@ multihash = { version = "*", default-features = false, features = [
"sha2",
"identity",
] }
uuid = { version = "0.8", features = ["v4"] }
uuid = { version = "0.8", features = ["v4", "serde"] }
url = { version = "2", features = ["serde"] }
nonempty = "0.6.0"

View File

@ -16,6 +16,12 @@ pub enum Address {
Url(Url),
}
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AddressComponents<'a> {
pub t: &'a str,
pub c: Option<&'a str>,
}
// multihash SHA2-256
const SHA2_256: u64 = 0x12;
// multihash identity
@ -69,6 +75,43 @@ impl Address {
)),
}
}
pub fn as_components(&self) -> AddressComponents {
// TODO: make this automatically derive from `Address` definition
let (entity_type, entity_content) = match self {
Address::Hash(_) => ("Hash", None),
Address::Uuid(_) => ("Uuid", None),
Address::Attribute(attribute) => ("Attribute", Some(attribute.as_str())),
Address::Url(url) => ("Url", Some(url.as_str())),
};
AddressComponents {
t: entity_type,
c: entity_content,
}
}
pub fn from_components(components: &AddressComponents) -> Result<Self> {
// TODO: make this automatically derive from `Address` definition
let address = match *components {
AddressComponents { t: "Attribute", c } => Address::Attribute(
c.map(|x| x.to_string())
.ok_or(anyhow!("Missing attribute."))?,
),
AddressComponents { t: "Url", c } => Address::Url(if let Some(string) = c {
Url::parse(&string)?
} else {
Err(anyhow!("Missing URL."))?
}),
AddressComponents { t: "Uuid", c } => match c {
Some(c) => c.parse()?,
None => Address::Uuid(Uuid::new_v4()),
},
AddressComponents { t, .. } => Err(anyhow!("Unknown attribute: \"{}\"", t))?,
};
Ok(address)
}
}
impl Serialize for Address {

View File

@ -18,7 +18,7 @@ use actix_web::{
http::header::{CacheControl, CacheDirective, DispositionType},
HttpRequest,
};
use anyhow::{anyhow, Result};
use anyhow::Result;
use futures::channel::oneshot;
use futures_util::{StreamExt, TryStreamExt};
use serde::{Deserialize, Serialize};
@ -30,6 +30,7 @@ use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use tempfile::NamedTempFile;
use tracing::{debug, info, trace};
use upend_base::addressing::AddressComponents;
use upend_base::addressing::{Address, Addressable};
use upend_base::constants::{ATTR_ADDED, ATTR_LABEL};
use upend_base::entry::{Entry, EntryValue, InvariantEntry};
@ -40,7 +41,6 @@ use upend_db::jobs;
use upend_db::stores::{Blob, UpStore};
use upend_db::UpEndDatabase;
use url::Url;
use uuid::Uuid;
#[cfg(feature = "desktop")]
use is_executable::IsExecutable;
@ -314,19 +314,8 @@ pub async fn get_object(
debug!("{:?}", result);
// TODO: make this automatically derive from `Address` definition
let (entity_type, entity_content) = match address {
Address::Hash(_) => ("Hash", None),
Address::Uuid(_) => ("Uuid", None),
Address::Attribute(attribute) => ("Attribute", Some(attribute)),
Address::Url(url) => ("Url", Some(url.to_string())),
};
Ok(HttpResponse::Ok().json(json!({
"entity": {
"t": entity_type,
"c": entity_content
},
"entity": address.as_components(),
"entries": result.as_hash().map_err(ErrorInternalServerError)?
})))
}
@ -344,23 +333,10 @@ impl TryInto<Address> for InAddress {
fn try_into(self) -> Result<Address, Self::Error> {
Ok(match self {
InAddress::Address(address) => address.parse()?,
InAddress::Components { t, c } => {
// I absolutely cannot handle serde magic right now
// TODO: make this automatically derive from `Address` definition
match t.as_str() {
"Attribute" => Address::Attribute(c.ok_or(anyhow!("Missing attribute."))?),
"Url" => Address::Url(if let Some(string) = c {
Url::parse(&string)?
} else {
Err(anyhow!("Missing URL."))?
}),
"Uuid" => match c {
Some(c) => c.parse()?,
None => Address::Uuid(Uuid::new_v4()),
},
_ => c.ok_or(anyhow!("Missing address."))?.parse()?,
}
}
InAddress::Components { t, c } => Address::from_components(&AddressComponents {
t: &t,
c: c.as_ref().map(|x| x.as_str()),
})?,
})
}
}
@ -1064,7 +1040,7 @@ mod tests {
assert_eq!(result["entity"]["t"], "Url");
assert_eq!(result["entity"]["c"], "https://upend.dev/");
let uuid = Uuid::new_v4();
let uuid = uuid::Uuid::new_v4();
let address = Address::Uuid(uuid);
let req = actix_web::test::TestRequest::get()
.uri(&format!("/api/obj/{}", address.to_string()))