contacts: make CardId an enum

CardId is the "Primary Key" of the contact type, Card. Meli-created
contacts had UUIDs for their CardId. In order to import external
contacts and ensure their primary key is the same each time, CardId is
made into an enum to add hashing as a choice.
embed
Manos Pitsidianakis 2019-10-20 11:06:26 +03:00
parent f3e08c17aa
commit dc525b9ddd
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
3 changed files with 47 additions and 7 deletions

View File

@ -28,7 +28,33 @@ use uuid::Uuid;
use std::ops::Deref;
pub type CardId = Uuid;
#[derive(Hash, Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize)]
#[serde(from = "String")]
#[serde(into = "String")]
pub enum CardId {
Uuid(Uuid),
Hash(u64),
}
impl Into<String> for CardId {
fn into(self) -> String {
match self {
CardId::Uuid(u) => u.to_string(),
CardId::Hash(u) => u.to_string(),
}
}
}
impl From<String> for CardId {
fn from(s: String) -> CardId {
if let Ok(u) = uuid::Uuid::parse_str(s.as_str()) {
CardId::Uuid(u)
} else {
use std::str::FromStr;
CardId::Hash(u64::from_str(&s).unwrap())
}
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AddressBook {
@ -95,7 +121,7 @@ impl Deref for AddressBook {
impl Card {
pub fn new() -> Card {
Card {
id: Uuid::new_v4(),
id: CardId::Uuid(Uuid::new_v4()),
title: String::new(),
name: String::new(),
additionalname: String::new(),
@ -145,8 +171,8 @@ impl Card {
self.last_edited.to_rfc2822()
}
pub fn set_id(&mut self, new: Uuid) {
self.id = new;
pub fn set_id(&mut self, new_val: CardId) {
self.id = new_val;
}
pub fn set_title(&mut self, new: String) {
self.title = new;

View File

@ -20,7 +20,7 @@
*/
/// Convert VCard strings to meli Cards (contacts).
use super::Card;
use super::*;
use crate::chrono::TimeZone;
use crate::error::{MeliError, Result};
use fnv::FnvHashMap;
@ -137,11 +137,25 @@ impl CardDeserializer {
}
}
impl std::convert::TryInto<Card> for VCard<VCardVersion4> {
impl<V: VCardVersion> std::convert::TryInto<Card> for VCard<V> {
type Error = crate::error::MeliError;
fn try_into(mut self) -> crate::error::Result<Card> {
let mut card = Card::new();
card.set_id(CardId::Hash({
use std::hash::Hasher;
let mut hasher = std::collections::hash_map::DefaultHasher::new();
if let Some(val) = self.0.get("FN") {
hasher.write(val.value.as_bytes());
}
if let Some(val) = self.0.get("N") {
hasher.write(val.value.as_bytes());
}
if let Some(val) = self.0.get("EMAIL") {
hasher.write(val.value.as_bytes());
}
hasher.finish()
}));
if let Some(val) = self.0.remove("FN") {
card.set_name(val.value);
} else {

View File

@ -7,7 +7,7 @@ const MAX_COLS: usize = 500;
#[derive(Debug, PartialEq)]
enum ViewMode {
List,
View(CardId),
View(ComponentId),
}
#[derive(Debug)]