summaryrefslogtreecommitdiffstats
path: root/bin/domain/imag-contact/src/util.rs
blob: 0910f644337fa9e02ad904f59c512c36bc2aed27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::collections::BTreeMap;

use failure::Fallible as Result;
use failure::err_msg;
use resiter::IterInnerOkOrElse;
use resiter::AndThen;

use libimagcontact::deser::DeserVcard;
use libimagcontact::store::ContactStore;
use libimagcontact::contact::Contact;
use libimagrt::runtime::Runtime;
use libimagstore::store::FileLockEntry;


pub fn build_data_object_for_handlebars(i: usize, vcard: &DeserVcard) -> BTreeMap<&'static str, String> {
    let mut data = BTreeMap::new();

    let process_list = |list: &Vec<String>| {
        list.iter()
            .map(String::clone)
            .collect::<Vec<_>>()
            .join(", ")
    };

    let process_opt  = |opt: Option<&String>| {
        opt.map(String::clone).unwrap_or_else(String::new)
    };

    {
        data.insert("i"            , format!("{}", i));

        // The hash (as in libimagentryref) of the contact
        data.insert("id"           , process_opt(vcard.uid()));
        data.insert("ADR"          , process_list(vcard.adr()));
        data.insert("ANNIVERSARY"  , process_opt(vcard.anniversary()));
        data.insert("BDAY"         , process_opt(vcard.bday()));
        data.insert("CATEGORIES"   , process_list(vcard.categories()));
        data.insert("CLIENTPIDMAP" , process_opt(vcard.clientpidmap()));
        data.insert("EMAIL"        , process_list(&vcard.email().iter().map(|a| a.address.clone()).collect()));
        data.insert("FN"           , process_list(vcard.fullname()));
        data.insert("GENDER"       , process_opt(vcard.gender()));
        data.insert("GEO"          , process_list(vcard.geo()));
        data.insert("IMPP"         , process_list(vcard.impp()));
        data.insert("KEY"          , process_list(vcard.key()));
        data.insert("LANG"         , process_list(vcard.lang()));
        data.insert("LOGO"         , process_list(vcard.logo()));
        data.insert("MEMBER"       , process_list(vcard.member()));
        data.insert("N"            , process_opt(vcard.name()));
        data.insert("NICKNAME"     , process_list(vcard.nickname()));
        data.insert("NOTE"         , process_list(vcard.note()));
        data.insert("ORG"          , process_list(vcard.org()));
        data.insert("PHOTO"        , process_list(vcard.photo()));
        data.insert("PRIOD"        , process_opt(vcard.proid()));
        data.insert("RELATED"      , process_list(vcard.related()));
        data.insert("REV"          , process_opt(vcard.rev()));
        data.insert("ROLE"         , process_list(vcard.role()));
        data.insert("SOUND"        , process_list(vcard.sound()));
        data.insert("TEL"          , process_list(vcard.tel()));
        data.insert("TITLE"        , process_list(vcard.title()));
        data.insert("TZ"           , process_list(vcard.tz()));
        data.insert("UID"          , process_opt(vcard.uid()));
        data.insert("URL"          , process_list(vcard.url()));
        data.insert("VERSION"      , process_opt(vcard.version()));
    }

    data
}

pub fn find_contact_by_hash<'a, H: AsRef<str>>(rt: &'a Runtime, hash: H)
    -> Result<impl Iterator<Item = Result<(bool, FileLockEntry<'a>)>>>
{
    Ok(rt.store()
        .all_contacts()?
        .into_get_iter()
        .map_inner_ok_or_else(|| err_msg("Did not find one entry"))
        .and_then_ok(move |entry| {
            let deser = entry.deser()?;

            let id_starts_with_hash = deser.uid()
                .ok_or_else(|| err_msg("Could not get StoreId from Store::all_contacts(). This is a BUG!"))?
                .starts_with(hash.as_ref());

            if id_starts_with_hash {
                rt.report_touched(entry.get_location())?;
            }

            Ok((id_starts_with_hash, entry))
        }))
}