contack 0.9.2

A simple and easy contact library.
Documentation
use contack::read_write::component::Component;
/// These test escaping strings.
use contack::read_write::escape;
use contack::read_write::vcard::VCard;
use contack::*;
use std::error::Error;

#[test]
fn escape_fold() {
    // Creates a string to fold
    let string = String::from("NOTE:This is a long description that exists on a long line. A very long line indeed.");

    // Folds a line
    assert_eq!("NOTE:This is a long description that exists on a long line. A very long lin\r\n\te indeed.", escape::fold_line(string.clone()));

    // Unfolds a line
    assert_eq!(
        escape::unfold_line(escape::fold_line(string.clone())),
        string
    );
}

#[test]
fn escape_property() {
    // Creates a property which we need to escape.
    let string = String::from("Alas, it was too late; the rocks began to fall\n\"No\", I whispered, \"We've failed\"\n \\ The End \\");

    // Escape it
    let escaped_string = escape::escape_property(string.as_str());

    assert_eq!(
        escaped_string,
        "Alas\\, it was too late\\; the rocks began to fall\\n\"No\"\\, I whispered\\, \"We've failed\"\\n \\\\ The End \\\\"
    );

    // Un escape it
    assert_eq!(escape::unescape_property(string.as_str()), string);
}

/// Makes sure that a component's group can be only set to an alphanumeric
/// + '-'
#[test]
fn component_group() {
    let mut component = Component::new("N".to_string());

    // Valid
    assert!(component.set_group(Some("foo".to_string())));
    assert!(component.set_group(Some("foo-bar".to_string())));
    assert!(component.set_group(Some("foo------bar".to_string())));
    assert!(component.set_group(Some("".to_string())));
    assert_eq!(component.get_group(), &None);

    // Invalid
    assert!(!component.set_group(Some("foo.bar".to_string())));
    assert!(!component.set_group(Some("°\\_(•⌷•)_/°".to_string())));
}

/// Tests converting to and from vcard for component
#[test]
fn component() -> Result<(), Box<dyn std::error::Error>> {
    let mut component = Component::new("N".to_string());
    assert!(component.set_group(Some("id".to_string())));
    component
        .parameters
        .insert("LANG".to_string(), "en".to_string());
    component.values = vec![
        vec!["Stevenson".to_string()],
        vec!["John".to_string()],
        vec!["Philip".to_string(), "Paul".to_string()],
        vec!["Dr.".to_string()],
        vec!["Jr.".to_string(), "M.D.".to_string(), "A.C.P.".to_string()],
    ];

    println!("{:#?}", component);

    println!("{}", component);

    assert_eq!(component, component.to_string().parse::<Component>()?);
    Ok(())
}

/// Tests all properties by converting from a VCard and back again.
#[test]
fn to_from_test() -> Result<(), Box<dyn Error>> {
    let vcard = include_str!("vcard.vcf");
    let vcard: VCard = vcard.parse()?;
    let contact: Contact = vcard.try_into()?;
    let vcard2: VCard = contact.clone().into();
    let vcard2 = vcard2.to_string();
    let vcard2: VCard = vcard2.parse()?;
    let contact2 = vcard2.try_into()?;

    assert_eq!(contact, contact2);
    println!("{:#?}", contact);

    Ok(())
}

#[test]
fn multi_vcard() {
    let vcard = include_str!("multi_vcard.vcf");
    let vcards: Vec<VCard> = VCard::from_str_to_vec(&vcard).unwrap();
    let mut contacts: Vec<Contact> = Vec::with_capacity(vcards.len());
    for vcard in vcards {
        contacts.push(vcard.try_into().unwrap())
    }
    assert_eq!(
        contacts,
        vec![
            Contact {
                uid: "7917f88b-c095-4226-b11b-433c4aea5feb".to_string(),
                name: contack::Name {
                    given: vec!["John".to_string()],
                    family: vec!["Doe".to_string()],
                    ..Default::default()
                },
                ..Contact::new(contack::Name::default())
            },
            Contact {
                uid: "83bd5b1e-7b9c-4067-9e0c-d8e187dc521e".to_string(),
                name: contack::Name {
                    given: vec!["Anne".to_string()],
                    family: vec!["Parker".to_string()],
                    ..Default::default()
                },
                ..Contact::new(contack::Name::default())
            }
        ]
    )
}