use alloc::{
borrow::{Cow, ToOwned},
format, vec,
};
use serde_json::{Map, Value};
use crate::{
jscalendar::export::{Builder, list, param, set, text},
param::IcalParamKind,
prop::IcalProp,
};
impl Builder {
pub(super) fn styled_description(&mut self, prop: &IcalProp<'_>) {
let Some(text) = text(prop) else {
return self.hatch.keep(prop);
};
let media = param(prop, IcalParamKind::FmtType).unwrap_or(Cow::Borrowed("text/html"));
self.object.insert(
"descriptionContentType".to_owned(),
Value::String(media.into_owned()),
);
self.member(
"description",
Value::String(text),
prop,
&[IcalParamKind::FmtType],
);
}
pub(super) fn privacy(&mut self, prop: &IcalProp<'_>) {
let Some(class) = text(prop) else {
return self.hatch.keep(prop);
};
let privacy = match class.to_ascii_uppercase().as_str() {
"CONFIDENTIAL" => "secret".to_owned(),
_ => class.to_lowercase(),
};
self.member("privacy", Value::String(privacy), prop, &[]);
}
pub(super) fn status(&mut self, prop: &IcalProp<'_>) {
let Some(status) = text(prop) else {
return self.hatch.keep(prop);
};
let pointer = match self.task {
true => "progress",
false => "status",
};
self.member(pointer, Value::String(status.to_lowercase()), prop, &[]);
}
pub(super) fn free_busy(&mut self, prop: &IcalProp<'_>) {
let Some(transp) = text(prop) else {
return self.hatch.keep(prop);
};
let status = match transp.to_ascii_uppercase().as_str() {
"TRANSPARENT" => "free",
"OPAQUE" => "busy",
_ => return self.hatch.keep(prop),
};
self.member(
"freeBusyStatus",
Value::String(status.to_owned()),
prop,
&[],
);
}
pub(super) fn keywords(&mut self, prop: &IcalProp<'_>) {
self.keywords.extend(set(list(prop)));
self.hatch.note("keywords", prop, &[]);
}
pub(super) fn concept(&mut self, prop: &IcalProp<'_>) {
match text(prop) {
Some(concept) => {
self.categories.insert(concept, Value::Bool(true));
self.hatch.note("categories", prop, &[]);
}
None => self.hatch.keep(prop),
}
}
pub(super) fn related(&mut self, prop: &IcalProp<'_>) {
let Some(uid) = text(prop) else {
return self.hatch.keep(prop);
};
let relation = param(prop, IcalParamKind::RelType)
.map(|kind| set(vec![kind.to_lowercase()]))
.unwrap_or_default();
let mut object = Map::new();
object.insert("@type".to_owned(), Value::String("Relation".to_owned()));
if !relation.is_empty() {
object.insert("relation".to_owned(), Value::Object(relation));
}
let pointer = format!("relatedTo/{uid}");
self.related_to.insert(uid, Value::Object(object));
self.hatch.note(&pointer, prop, &[IcalParamKind::RelType]);
}
}