2个不稳定版本
0.2.0 | 2023年3月29日 |
---|---|
0.1.0 | 2023年3月28日 |
#1240 在 解析器实现
每月21次下载
70KB
1.5K SLoC
ical_vcard
ical_vcard 提供了iCalendar (RFC 5545) 和 vCard (RFC 6350) 数据格式内容行格式的解析器和写入器实现。它不是这两个标准的完整实现。相反,ical_vcard 旨在作为一个基础,可以在此基础上构建完整的iCalendar或vCard解析器和写入器。
当然,可以使用此crate来解析iCalendar或vCard文件。然而,它不能提供专门iCalendar或vCard库能提供的便利或所有功能。
功能
- 内容行解析器
- 内容行写入器/格式化器
- 遵循RFC 5545 和 RFC 6350。特别是,解析器和写入器遵循 RFC5545第3.1节 和 RFC6350第3节,描述了内容行格式。
- 遵循RFC 6868,它通过编码双引号和行断行符的转义规则更新了RFC 5545 和 RFC 6350。
示例:解析生日
此示例演示了如何将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