use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use sp_std::vec::Vec;
use kilt_asset_dids::AssetDid as AssetIdentifier;
use kilt_support::traits::ItemFilter;
use public_credentials::CredentialEntry;
use crate::{authorization::AuthorizationId, AccountId, Balance, BlockNumber, Hash};
#[cfg(feature = "runtime-benchmarks")]
pub use benchmarks::*;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct AssetDid(AssetIdentifier);
impl core::ops::Deref for AssetDid {
type Target = AssetIdentifier;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl TryFrom<Vec<u8>> for AssetDid {
type Error = &'static str;
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
let asset = AssetIdentifier::from_utf8_encoded(&value[..])
.map_err(|_| "Cannot convert provided input to a valid Asset DID.")?;
Ok(Self(asset))
}
}
#[cfg(feature = "std")]
impl TryFrom<String> for AssetDid {
type Error = &'static str;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::try_from(value.into_bytes())
}
}
#[derive(Encode, Decode, TypeInfo)]
pub enum PublicCredentialsFilter<CTypeHash, Attester> {
CtypeHash(CTypeHash),
Attester(Attester),
}
impl ItemFilter<CredentialEntry<Hash, AccountId, BlockNumber, AccountId, Balance, AuthorizationId<Hash>>>
for PublicCredentialsFilter<Hash, AccountId>
{
fn should_include(
&self,
credential: &CredentialEntry<Hash, AccountId, BlockNumber, AccountId, Balance, AuthorizationId<Hash>>,
) -> bool {
match self {
Self::CtypeHash(ctype_hash) => ctype_hash == &credential.ctype_hash,
Self::Attester(attester) => attester == &credential.attester,
}
}
}
#[cfg(feature = "runtime-benchmarks")]
mod benchmarks {
use super::*;
use parity_scale_codec::alloc::string::ToString;
use sp_std::vec::Vec;
use kilt_asset_dids::{asset, chain};
impl From<AssetDid> for Vec<u8> {
fn from(value: AssetDid) -> Self {
value.to_string().as_bytes().to_vec()
}
}
impl<Context> kilt_support::traits::GetWorstCase<Context> for AssetDid {
type Output = Self;
fn worst_case(_context: Context) -> Self::Output {
Self::try_from(
[
b"did:asset:",
&[b'0'; chain::MAXIMUM_CHAIN_NAMESPACE_LENGTH][..],
b":",
&[b'1'; chain::MAXIMUM_CHAIN_REFERENCE_LENGTH][..],
b".",
&[b'2'; asset::MAXIMUM_NAMESPACE_LENGTH][..],
b":",
&[b'3'; asset::MAXIMUM_ASSET_REFERENCE_LENGTH][..],
b":",
&[b'4'; asset::MAXIMUM_ASSET_IDENTIFIER_LENGTH][..],
]
.concat(),
)
.expect("Worst case creation should not fail.")
}
}
}