142 lines
4.2 KiB
Rust
142 lines
4.2 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*/
|
|
|
|
use crate::error::Error;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub enum ObjectType {
|
|
Mailbox,
|
|
Email,
|
|
Identity,
|
|
SieveScript,
|
|
AddressBook,
|
|
ContactCard,
|
|
Calendar,
|
|
CalendarEvent,
|
|
ParticipantIdentity,
|
|
FileNode,
|
|
}
|
|
|
|
impl ObjectType {
|
|
pub const ALL: [ObjectType; 10] = [
|
|
ObjectType::Mailbox,
|
|
ObjectType::Email,
|
|
ObjectType::Identity,
|
|
ObjectType::SieveScript,
|
|
ObjectType::AddressBook,
|
|
ObjectType::ContactCard,
|
|
ObjectType::Calendar,
|
|
ObjectType::CalendarEvent,
|
|
ObjectType::ParticipantIdentity,
|
|
ObjectType::FileNode,
|
|
];
|
|
|
|
pub fn token(self) -> &'static str {
|
|
match self {
|
|
ObjectType::Mailbox => "mailbox",
|
|
ObjectType::Email => "email",
|
|
ObjectType::Identity => "identity",
|
|
ObjectType::SieveScript => "sievescript",
|
|
ObjectType::AddressBook => "addressbook",
|
|
ObjectType::ContactCard => "contactcard",
|
|
ObjectType::Calendar => "calendar",
|
|
ObjectType::CalendarEvent => "calendarevent",
|
|
ObjectType::ParticipantIdentity => "participantidentity",
|
|
ObjectType::FileNode => "filenode",
|
|
}
|
|
}
|
|
|
|
pub fn jmap_name(self) -> &'static str {
|
|
match self {
|
|
ObjectType::Mailbox => "Mailbox",
|
|
ObjectType::Email => "Email",
|
|
ObjectType::Identity => "Identity",
|
|
ObjectType::SieveScript => "SieveScript",
|
|
ObjectType::AddressBook => "AddressBook",
|
|
ObjectType::ContactCard => "ContactCard",
|
|
ObjectType::Calendar => "Calendar",
|
|
ObjectType::CalendarEvent => "CalendarEvent",
|
|
ObjectType::ParticipantIdentity => "ParticipantIdentity",
|
|
ObjectType::FileNode => "FileNode",
|
|
}
|
|
}
|
|
|
|
pub fn capability_urn(self) -> &'static str {
|
|
match self {
|
|
ObjectType::Mailbox | ObjectType::Email => "urn:ietf:params:jmap:mail",
|
|
ObjectType::Identity => "urn:ietf:params:jmap:submission",
|
|
ObjectType::SieveScript => "urn:ietf:params:jmap:sieve",
|
|
ObjectType::AddressBook | ObjectType::ContactCard => "urn:ietf:params:jmap:contacts",
|
|
ObjectType::Calendar | ObjectType::CalendarEvent | ObjectType::ParticipantIdentity => {
|
|
"urn:ietf:params:jmap:calendars"
|
|
}
|
|
ObjectType::FileNode => "urn:ietf:params:jmap:filenode",
|
|
}
|
|
}
|
|
|
|
pub fn parse(token: &str) -> Result<ObjectType, Error> {
|
|
let normalized = token.trim().to_ascii_lowercase();
|
|
ObjectType::ALL
|
|
.into_iter()
|
|
.find(|t| t.token() == normalized)
|
|
.ok_or_else(|| Error::Usage(format!("unknown object type: {token}")))
|
|
}
|
|
}
|
|
|
|
pub fn parse_object_list(list: &str) -> Result<Vec<ObjectType>, Error> {
|
|
let mut out = Vec::new();
|
|
for token in list.split(',') {
|
|
let token = token.trim();
|
|
if token.is_empty() {
|
|
continue;
|
|
}
|
|
let parsed = ObjectType::parse(token)?;
|
|
if !out.contains(&parsed) {
|
|
out.push(parsed);
|
|
}
|
|
}
|
|
if out.is_empty() {
|
|
return Err(Error::Usage(
|
|
"--objects given but resolved to an empty type list".to_owned(),
|
|
));
|
|
}
|
|
Ok(out)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn token_roundtrip() {
|
|
for t in ObjectType::ALL {
|
|
assert_eq!(ObjectType::parse(t.token()).unwrap(), t);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn parse_list_dedups_and_trims() {
|
|
let parsed = parse_object_list(" mailbox, email ,mailbox").unwrap();
|
|
assert_eq!(parsed, vec![ObjectType::Mailbox, ObjectType::Email]);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_list_case_insensitive() {
|
|
let parsed = parse_object_list("Mailbox,EMAIL").unwrap();
|
|
assert_eq!(parsed, vec![ObjectType::Mailbox, ObjectType::Email]);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_list_rejects_unknown() {
|
|
assert!(parse_object_list("mailbox,bogus").is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn parse_list_rejects_empty() {
|
|
assert!(parse_object_list(" , ").is_err());
|
|
}
|
|
}
|