17 releases
0.5.2 | Jun 28, 2024 |
---|---|
0.5.0 | Feb 9, 2024 |
0.4.4 | Apr 18, 2023 |
0.4.3 | Mar 20, 2023 |
0.1.4 | Nov 9, 2022 |
#145 in Date and time
446 downloads per month
Used in 8 crates
(3 directly)
155KB
4K
SLoC
vCard
Fast and correct vCard parser based on RFC6350; see the API documentation for more information.
For interoperability with older software the parser will accept input with a CHARSET
parameter that has a value of UTF-8
, any other encoding value for CHARSET
will generate an error. However, this parameter is not part of RFC6350 and is therefore not included in the string output for a vCard.
License is MIT or Apache-2.0.
lib.rs
:
Fast and correct vCard parser based on RFC6350.
vCards inherently contain private information so this library
implements a zeroize
feature (which is enabled by default) to
securely zero the memory for all the data in a vCard when it is
dropped.
Certain external types cannot be zeroize'd due to the restrictions on implementing external traits on external types and are therefore exempt:
Uri
Time
/UtcOffset
/OffsetDateTime
LanguageTag
(feature:language-tags
)Mime
(feature:mime
)
If the mime
feature is enabled the MEDIATYPE parameter is parsed
to a Mime
struct otherwise it is a String
.
If the language-tags
feature is enabled the LANG property
and the LANGUAGE parameter are parsed using the
language-tags crate.
Serde support can be enabled with the serde
feature.
Examples
Create a new vCard:
use vcard4::VcardBuilder;
let card = VcardBuilder::new("John Doe".to_owned())
.nickname("Johnny".to_owned())
.finish();
print!("{}", card);
Decoding and encoding:
use anyhow::Result;
use vcard4::parse;
pub fn main() -> Result<()> {
let input = r#"BEGIN:VCARD
VERSION:4.0
FN:John Doe
NICKNAME:Johnny
END:VCARD"#;
let cards = parse(input)?;
let card = cards.first().unwrap();
let encoded = card.to_string();
let decoded = parse(&encoded)?.remove(0);
assert_eq!(card, &decoded);
Ok(())
}
Iterative parsing is useful if you only need the first vCard or wish to ignore vCards that have errors (possibly during an import operation):
use anyhow::Result;
use vcard4::iter;
pub fn main() -> Result<()> {
let input = r#"BEGIN:VCARD
VERSION:4.0
FN:John Doe
END:VCARD
BEGIN:VCARD
VERSION:4.0
FN:Jane Doe
END:VCARD"#;
let mut it = iter(input, true);
print!("{}", it.next().unwrap()?);
print!("{}", it.next().unwrap()?);
assert!(matches!(it.next(), None));
Ok(())
}
Implementation
- The
XML
property is parsed and propagated but it is not validated as it is optional in the RFC. - IANA Tokens are not implemented.
- The RFC requires a CRLF sequence for line breaks but for easier interoperability between platforms we treat the carriage return as optional.
Dependencies
~5MB
~66K SLoC