Migrate (#4)
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
use std::io::BufRead;
|
||||
|
||||
const LETTERS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct NumberParser {
|
||||
pub filepath: String,
|
||||
}
|
||||
|
||||
impl NumberParser {
|
||||
pub async fn file_dump(
|
||||
&self,
|
||||
) -> Result<Vec<textsender_models::contact::Contact>, std::io::Error> {
|
||||
println!("Dumping files");
|
||||
let mut objs: Vec<textsender_models::contact::Contact> = Vec::new();
|
||||
|
||||
match self.read_lines(&self.filepath).await {
|
||||
Ok(lines) => {
|
||||
for line in lines {
|
||||
let contains_letters = line.chars().any(|c| LETTERS.contains(c));
|
||||
if contains_letters {
|
||||
continue;
|
||||
} else {
|
||||
let my_obj = textsender_models::contact::Contact {
|
||||
phone_number: line.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
if !my_obj.phone_number.is_empty() {
|
||||
objs.push(my_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let updated_contacts = self.update_contacts(&objs).await;
|
||||
let removed_duplicates = self.remove_dups(&updated_contacts).await;
|
||||
|
||||
Ok(removed_duplicates)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save_file(&self, numbers: Vec<textsender_models::contact::Contact>) {
|
||||
let filename = String::from("numbers.json");
|
||||
|
||||
match serde_json::to_string(&numbers) {
|
||||
Ok(json_string) => match std::fs::write(&filename, json_string) {
|
||||
Ok(_) => {
|
||||
println!("Saved to: {filename:?}");
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn print_phone_numbers(&self, contacts: &Vec<textsender_models::contact::Contact>) {
|
||||
println!("Printing phone numbers");
|
||||
|
||||
for contact in contacts {
|
||||
println!("Phone Number: {:?}", contact.phone_number);
|
||||
}
|
||||
|
||||
println!("Total phone numbers: {:?}", contacts.len());
|
||||
}
|
||||
|
||||
async fn read_lines(&self, filename: &String) -> Result<Vec<String>, std::io::Error> {
|
||||
match std::fs::File::open(filename) {
|
||||
Ok(file) => {
|
||||
let reader = std::io::BufReader::new(file);
|
||||
reader.lines().collect()
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
async fn remove_dups(
|
||||
&self,
|
||||
contacts: &Vec<textsender_models::contact::Contact>,
|
||||
) -> Vec<textsender_models::contact::Contact> {
|
||||
let mut unique_contacts: Vec<textsender_models::contact::Contact> = Vec::new();
|
||||
let mut unique_items = std::collections::HashSet::new();
|
||||
|
||||
for val in contacts {
|
||||
unique_items.insert(val.phone_number.clone());
|
||||
}
|
||||
|
||||
for unique_item in unique_items {
|
||||
let contact = textsender_models::contact::Contact {
|
||||
phone_number: unique_item,
|
||||
..Default::default()
|
||||
};
|
||||
unique_contacts.push(contact);
|
||||
}
|
||||
|
||||
unique_contacts
|
||||
}
|
||||
|
||||
async fn update_contacts(
|
||||
&self,
|
||||
contacts: &Vec<textsender_models::contact::Contact>,
|
||||
) -> Vec<textsender_models::contact::Contact> {
|
||||
let mut updated: Vec<textsender_models::contact::Contact> = Vec::new();
|
||||
|
||||
for ct in contacts {
|
||||
let phone_number = ct.phone_number.clone();
|
||||
if phone_number.len() < 2 {
|
||||
println!("Invalid number: {phone_number:?}");
|
||||
continue;
|
||||
}
|
||||
|
||||
let pars = self.remove_some_data(&phone_number).await;
|
||||
|
||||
match self.add_prefix(&pars) {
|
||||
Ok(updated_parsed) => {
|
||||
let contact = textsender_models::contact::Contact {
|
||||
phone_number: updated_parsed,
|
||||
..Default::default()
|
||||
};
|
||||
updated.push(contact);
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
std::process::exit(-2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
updated
|
||||
}
|
||||
|
||||
fn add_prefix(&self, raw: &String) -> Result<String, std::io::Error> {
|
||||
if raw.is_empty() {
|
||||
Err(std::io::Error::other("Empty"))
|
||||
} else {
|
||||
let mut parsed: String = String::new();
|
||||
let first_char = raw.chars().nth(0).unwrap();
|
||||
|
||||
if first_char == '1' {
|
||||
parsed = format!("+{raw}");
|
||||
} else if first_char != '+' {
|
||||
parsed = format!("+1{raw}");
|
||||
}
|
||||
|
||||
Ok(parsed)
|
||||
}
|
||||
}
|
||||
|
||||
async fn remove_some_data(&self, unparsed: &str) -> String {
|
||||
let mut parsed: String = String::new();
|
||||
|
||||
for ch in unparsed.chars() {
|
||||
if ch == ' ' {
|
||||
continue;
|
||||
} else {
|
||||
if ch.is_numeric() {
|
||||
parsed.push(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parsed
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user