Legacy vCard 2.1 and 3.0 serialization support
This commit is contained in:
@@ -14,7 +14,7 @@ directory = { path = "../directory" }
|
||||
http_proto = { path = "../http-proto" }
|
||||
jmap_proto = { path = "../jmap-proto" }
|
||||
trc = { path = "../trc" }
|
||||
calcard = { version = "0.1", features = ["rkyv"] }
|
||||
calcard = { version = "0.1.1", features = ["rkyv"] }
|
||||
hashify = { version = "0.2" }
|
||||
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
|
||||
percent-encoding = "2.3.1"
|
||||
|
||||
@@ -105,7 +105,14 @@ impl CardGetRequestHandler for Server {
|
||||
.with_etag(etag)
|
||||
.with_last_modified(Rfc1123DateTime::new(i64::from(card.modified)).to_string());
|
||||
|
||||
let vcard = card.card.to_string();
|
||||
let mut vcard = String::with_capacity(128);
|
||||
let _ = card.card.write_to(
|
||||
&mut vcard,
|
||||
headers
|
||||
.max_vcard_version
|
||||
.or_else(|| card.card.version())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
if !is_head {
|
||||
Ok(response.with_binary_body(vcard))
|
||||
|
||||
@@ -13,7 +13,8 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use calcard::vcard::{
|
||||
ArchivedVCard, ArchivedVCardEntry, ArchivedVCardParameter, VCardParameterName,
|
||||
ArchivedVCard, ArchivedVCardEntry, ArchivedVCardParameter, VCardParameterName, VCardProperty,
|
||||
VCardVersion,
|
||||
};
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{
|
||||
@@ -200,22 +201,30 @@ fn find_parameter<'x>(
|
||||
pub(crate) fn serialize_vcard_with_props(
|
||||
card: &ArchivedVCard,
|
||||
props: &[CardDavPropertyName],
|
||||
version: Option<VCardVersion>,
|
||||
) -> String {
|
||||
let mut vcard = String::with_capacity(128);
|
||||
let version = version.or_else(|| card.version()).unwrap_or_default();
|
||||
if !props.is_empty() {
|
||||
let mut vcard = String::with_capacity(128);
|
||||
let _ = write!(&mut vcard, "BEGIN:VCARD\r\n");
|
||||
let is_v4 = matches!(version, VCardVersion::V4_0);
|
||||
|
||||
for entry in card.entries.iter() {
|
||||
for item in props {
|
||||
if entry.name == item.name && entry.group == item.group {
|
||||
let _ = entry.write_to(&mut vcard, !item.no_value);
|
||||
if item.name != VCardProperty::Version {
|
||||
let _ = entry.write_to(&mut vcard, !item.no_value, is_v4);
|
||||
} else {
|
||||
let _ = write!(&mut vcard, "VERSION:{version}\r\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = write!(&mut vcard, "END:VCARD\r\n");
|
||||
vcard
|
||||
} else {
|
||||
card.to_string()
|
||||
let _ = card.write_to(&mut vcard, version);
|
||||
}
|
||||
|
||||
vcard
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use calcard::{
|
||||
icalendar::{ICalendarComponentType, ICalendarParameterName, ICalendarProperty},
|
||||
vcard::VCardParameterName,
|
||||
vcard::{VCardParameterName, VCardVersion},
|
||||
};
|
||||
use dav_proto::{
|
||||
Depth, RequestHeaders, Return,
|
||||
@@ -35,7 +35,7 @@ pub mod lock;
|
||||
pub mod propfind;
|
||||
pub mod uri;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DavQuery<'x> {
|
||||
pub uri: &'x str,
|
||||
pub resource: DavQueryResource<'x>,
|
||||
@@ -43,6 +43,7 @@ pub(crate) struct DavQuery<'x> {
|
||||
pub sync_type: SyncType,
|
||||
pub depth: usize,
|
||||
pub limit: Option<u32>,
|
||||
pub max_vcard_version: Option<VCardVersion>,
|
||||
pub ret: Return,
|
||||
pub depth_no_root: bool,
|
||||
pub expand: bool,
|
||||
@@ -158,7 +159,10 @@ impl<'x> DavQuery<'x> {
|
||||
ret: headers.ret,
|
||||
depth_no_root: headers.depth_no_root,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
max_vcard_version: headers.max_vcard_version,
|
||||
sync_type: Default::default(),
|
||||
limit: Default::default(),
|
||||
expand: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +180,11 @@ impl<'x> DavQuery<'x> {
|
||||
ret: headers.ret,
|
||||
depth_no_root: headers.depth_no_root,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
max_vcard_version: headers.max_vcard_version,
|
||||
sync_type: Default::default(),
|
||||
depth: Default::default(),
|
||||
limit: Default::default(),
|
||||
expand: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +204,10 @@ impl<'x> DavQuery<'x> {
|
||||
ret: headers.ret,
|
||||
depth_no_root: headers.depth_no_root,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
max_vcard_version: headers.max_vcard_version,
|
||||
sync_type: Default::default(),
|
||||
depth: Default::default(),
|
||||
expand: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +231,11 @@ impl<'x> DavQuery<'x> {
|
||||
ret: headers.ret,
|
||||
depth_no_root: headers.depth_no_root,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
sync_type: Default::default(),
|
||||
depth: Default::default(),
|
||||
limit: Default::default(),
|
||||
max_vcard_version: Default::default(),
|
||||
expand: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +264,7 @@ impl<'x> DavQuery<'x> {
|
||||
depth_no_root: headers.depth_no_root,
|
||||
expand: false,
|
||||
uri: headers.uri,
|
||||
max_vcard_version: headers.max_vcard_version,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +293,9 @@ impl<'x> DavQuery<'x> {
|
||||
depth_no_root: headers.depth_no_root,
|
||||
expand: true,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
sync_type: Default::default(),
|
||||
limit: Default::default(),
|
||||
max_vcard_version: headers.max_vcard_version,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1191,6 +1191,9 @@ impl PropFindRequestHandler for Server {
|
||||
DavValue::CData(serialize_vcard_with_props(
|
||||
&card.inner.card,
|
||||
items,
|
||||
query
|
||||
.max_vcard_version
|
||||
.or_else(|| card.inner.card.version()),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -69,7 +69,10 @@ impl PrincipalMatching for Server {
|
||||
ret: headers.ret,
|
||||
depth_no_root: headers.depth_no_root,
|
||||
uri: headers.uri,
|
||||
..Default::default()
|
||||
sync_type: Default::default(),
|
||||
limit: Default::default(),
|
||||
max_vcard_version: Default::default(),
|
||||
expand: Default::default(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user