#![doc(html_root_url = "https://docs.rs/ic-cose-types/latest")]
#![allow(clippy::needless_doctest_main)]
use candid::{utils::ArgumentEncoder, CandidType, Principal};
use ciborium::into_writer;
use serde::Serialize;
use std::{collections::BTreeSet, future::Future, ops::Deref};
pub mod cose;
pub mod types;
pub use cose::format_error;
pub static ANONYMOUS: Principal = Principal::anonymous();
pub const MILLISECONDS: u64 = 1_000_000u64;
pub fn to_cbor_bytes(obj: &impl Serialize) -> Vec<u8> {
let mut buf: Vec<u8> = Vec::new();
into_writer(obj, &mut buf).expect("failed to encode in CBOR format");
buf
}
pub fn validate_str(s: &str) -> Result<(), String> {
if s.is_empty() {
return Err("empty string".to_string());
}
if s.len() > 64 {
return Err("string length exceeds the limit 64".to_string());
}
for c in s.chars() {
if !matches!(c, 'a'..='z' | '0'..='9' | '_' ) {
return Err(format!("invalid character: {}", c));
}
}
Ok(())
}
pub fn validate_principals(principals: &BTreeSet<Principal>) -> Result<(), String> {
if principals.is_empty() {
return Err("principals cannot be empty".to_string());
}
if principals.contains(&ANONYMOUS) {
return Err("anonymous user is not allowed".to_string());
}
Ok(())
}
pub enum OwnedRef<'a, T> {
Ref(&'a T),
Owned(T),
}
impl<T> AsRef<T> for OwnedRef<'_, T> {
fn as_ref(&self) -> &T {
match self {
OwnedRef::Ref(r) => r,
OwnedRef::Owned(o) => o,
}
}
}
impl<T> Deref for OwnedRef<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
OwnedRef::Ref(r) => r,
OwnedRef::Owned(o) => o,
}
}
}
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
pub trait CanisterCaller: Sized {
fn canister_query<
In: ArgumentEncoder + Send,
Out: CandidType + for<'a> candid::Deserialize<'a>,
>(
&self,
canister: &Principal,
method: &str,
args: In,
) -> impl Future<Output = Result<Out, BoxError>> + Send;
fn canister_update<
In: ArgumentEncoder + Send,
Out: CandidType + for<'a> candid::Deserialize<'a>,
>(
&self,
canister: &Principal,
method: &str,
args: In,
) -> impl Future<Output = Result<Out, BoxError>> + Send;
}