pub mod create;
pub mod delete;
pub mod enumerate;
pub mod list;
pub mod multiget;
pub mod read;
pub mod update;
use alloc::{
format,
string::{String, ToString},
vec::Vec,
};
use crate::{
rfc4918::{GETETAG, Property, ResponseEntry, trace_unrecognized},
rfc6352::addressbook::ADDRESS_DATA,
};
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CardRef {
pub id: String,
pub uri: String,
pub etag: Option<String>,
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CardEntry {
pub id: String,
pub uri: String,
pub etag: Option<String>,
pub data: Vec<u8>,
}
pub(crate) const CARD_PROPS: &[Property] = &[GETETAG, ADDRESS_DATA];
pub fn join_path(addressbook: &str, uri: &str) -> String {
let addressbook = addressbook.trim_end_matches('/');
let uri = uri.trim_start_matches('/');
format!("{addressbook}/{uri}")
}
pub(crate) fn card_from_entry(entry: &ResponseEntry) -> Option<CardEntry> {
if entry.href.ends_with('/') {
return None;
}
let uri = entry.id();
let id = uri.trim_end_matches(".vcf");
if id.is_empty() {
return None;
}
let data = entry.text(ADDRESS_DATA)?;
trace_unrecognized(entry, CARD_PROPS);
Some(CardEntry {
id: id.to_string(),
uri: uri.to_string(),
etag: entry
.text(GETETAG)
.map(|raw| raw.trim_matches('"').to_string()),
data: data.as_bytes().to_vec(),
})
}