#ical #vcard #parser #line-break

ical_vcard

用于vCard和iCalendar中内容行格式的解析器和写入器

2个不稳定版本

0.2.0 2023年3月29日
0.1.0 2023年3月28日

#1240解析器实现

每月21次下载

MIT/Apache

70KB
1.5K SLoC

ical_vcard

ical_vcard 提供了iCalendar (RFC 5545) 和 vCard (RFC 6350) 数据格式内容行格式的解析器和写入器实现。它不是这两个标准的完整实现。相反,ical_vcard 旨在作为一个基础,可以在此基础上构建完整的iCalendar或vCard解析器和写入器。

当然,可以使用此crate来解析iCalendar或vCard文件。然而,它不能提供专门iCalendar或vCard库能提供的便利或所有功能。

功能

示例:解析生日

此示例演示了如何将vCard文件转换为将姓名映射到生日的 HashMap

use {
    ical_vcard::Parser,
    std::collections::HashMap,
};

let vcard_file = "\
BEGIN:VCARD\r
FN:Mark Daniels\r
BDAY:19830525\r
END:VCARD\r
BEGIN:VCARD\r
FN:Peter Smith\r
BDAY:19770525\r
EMAIL:[email protected]\r
END:VCARD\r
BEGIN:VCARD\r
BDAY:19800521\r
FN:Jack Black\r
END:VCARD\r
".as_bytes();

let birthdays: HashMap<_, _> = Parser::new(vcard_file)
    .collect::<Result<Vec<_>, _>>()
    .expect("valid vcard file")
    .split(|contentline| contentline.name == "BEGIN" && contentline.value == "VCARD")
    .flat_map(|vcard| {
        let name = vcard
            .iter()
            .find(|contentline| contentline.name == "FN")?
            .value
            .value()
            .to_owned();
        let birthday = vcard
            .iter()
            .find(|contentline| contentline.name == "BDAY")?
            .value
            .value()
            .to_owned();

        Some((name, birthday))
    })
    .collect();

assert_eq!(birthdays["Peter Smith"], "19770525");
assert_eq!(birthdays["Jack Black"], "19800521");
assert_eq!(birthdays["Mark Daniels"], "19830525");

示例:姓名 & 电子邮件地址

此示例说明了如何写入vCard文件。

use ical_vcard::{Contentline, Identifier, Param, ParamValue, Value, Writer};

let names = [
    "Aristotle",
    "Plato",
    "Pythagoras",
    "Thales",
];

let contentlines = names.into_iter().flat_map(|name| [
    Contentline {
        group: None,
        name: Identifier::new("BEGIN").unwrap(),
        params: Vec::new(),
        value: Value::new("VCARD").unwrap(),
    },
    Contentline {
        group: None,
        name: Identifier::new("FN").unwrap(),
        params: Vec::new(),
        value: Value::new(name).unwrap(),
    },
    Contentline {
        group: None,
        name: Identifier::new("N").unwrap(),
        params: Vec::new(),
        value: Value::new(format!(";{name};;;")).unwrap(),
    },
    Contentline {
        group: None,
        name: Identifier::new("EMAIL").unwrap(),
        params: vec![Param::new(
            Identifier::new("TYPE").unwrap(),
            vec![ParamValue::new("work").unwrap()]
        ).unwrap()],
        value: Value::new(
            format!("{name}@ancient-philosophers.gr", name = name.to_lowercase())
        ).unwrap(),
    },
    Contentline {
        group: None,
        name: Identifier::new("END").unwrap(),
        params: Vec::new(),
        value: Value::new("VCARD").unwrap(),
    },
]);

let vcard = {
    let mut buffer = Vec::new();
    let mut writer = Writer::new(&mut buffer);
    writer.write_all(contentlines).expect("write to Vec should cause no errors");
    buffer
};

let expected = "\
BEGIN:VCARD\r
FN:Aristotle\r
N:;Aristotle;;;\r
EMAIL;TYPE=work:[email protected]\r
END:VCARD\r
BEGIN:VCARD\r
FN:Plato\r
N:;Plato;;;\r
EMAIL;TYPE=work:[email protected]\r
END:VCARD\r
BEGIN:VCARD\r
FN:Pythagoras\r
N:;Pythagoras;;;\r
EMAIL;TYPE=work:[email protected]\r
END:VCARD\r
BEGIN:VCARD\r
FN:Thales\r
N:;Thales;;;\r
EMAIL;TYPE=work:[email protected]\r
END:VCARD\r
".as_bytes();

assert_eq!(vcard, expected);

许可证

本项目受MIT许可证Apache许可证2.0版本许可。

软件按“原样”提供,不提供任何形式的保证,无论是明示的还是隐含的,包括但不限于对适销性、特定用途的适用性和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他原因,无论这些责任是否源于、因之而发或与该软件或其使用或其他任何方式有关。

依赖项

~275–730KB
~17K SLoC