Skip to content

Commit

Permalink
re-use some code
Browse files Browse the repository at this point in the history
  • Loading branch information
a-moreira committed Jul 6, 2023
1 parent b737838 commit 528dac8
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 81 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ edition = "2021"
rust-version = "1.61" # MSRV (also change in CI)

[dependencies]
dialoguer = { version = "0.10", features = ["completion"] }
serde = { version = "1.0.120", features = ["rc"] }
serde_json = "1.0.61"
serde_derive = "1.0.120"
Expand Down
47 changes: 1 addition & 46 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use console::{style, Term};
use dialoguer::{Completion, Input};
use futures::{future::Either, Future, FutureExt};
use indicatif::{MultiProgress, ProgressBar};
use magic_wormhole::PgpWordList;
use magic_wormhole::{forwarding, transfer, transit, Wormhole};
use std::{
collections::HashMap,
Expand Down Expand Up @@ -704,52 +705,6 @@ fn create_progress_bar(file_size: u64) -> ProgressBar {
pb
}

struct PgpWordList {
even_words: Vec<String>,
odd_words: Vec<String>,
}

impl Default for PgpWordList {
fn default() -> Self {
let json = fs::read_to_string("./src/core/pgpwords.json").unwrap();
let word_map: HashMap<String, Vec<String>> = serde_json::from_str(&json).unwrap();
let mut even_words: Vec<String> = vec![];
let mut odd_words: Vec<String> = vec![];
for (_idx, words) in word_map {
even_words.push(words[0].to_lowercase());
odd_words.push(words[1].to_lowercase());
}

PgpWordList {
even_words,
odd_words,
}
}
}

impl Completion for PgpWordList {
fn get(&self, input: &str) -> Option<String> {
let count = input.matches("-").count();
// we start with the odd words
let word_list: Vec<String> = if count % 2 == 0 {
self.odd_words.clone()
} else {
self.even_words.clone()
};

let matches = word_list
.iter()
.filter(|word| word.starts_with(input))
.collect::<Vec<_>>();

if matches.len() == 1 {
Some(matches[0].to_string())
} else {
None
}
}
}

fn enter_code() -> eyre::Result<String> {
let completion = PgpWordList::default();
let input = Input::new()
Expand Down
2 changes: 1 addition & 1 deletion src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod rendezvous;
mod server_messages;
#[cfg(test)]
mod test;
mod wordlist;
pub mod wordlist;

use serde_derive::{Deserialize, Serialize};
use std::borrow::Cow;
Expand Down
85 changes: 52 additions & 33 deletions src/core/wordlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,69 @@ use rand::{rngs::OsRng, seq::SliceRandom};
use serde_json::{self, Value};
use std::fmt;

#[derive(PartialEq)]
pub struct Wordlist {
pub num_words: usize,
use dialoguer::Completion;
use std::collections::HashMap;
use std::fs;

pub struct PgpWordList {
words: Vec<Vec<String>>,
num_words: usize,
}

impl fmt::Debug for Wordlist {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Wordlist ( {}, lots of words...)", self.num_words)
impl PgpWordList {
pub fn choose_words(&self) -> String {
let mut rng = OsRng;
let components: Vec<String>;
components = self
.words
.iter()
.cycle()
.take(self.num_words)
.map(|words| words.choose(&mut rng).unwrap().to_string())
.collect();
components.join("-")
}
}

impl Wordlist {
#[cfg(test)]
pub fn new(num_words: usize, words: Vec<Vec<String>>) -> Wordlist {
Wordlist { num_words, words }
impl Default for PgpWordList {
fn default() -> Self {
let json = fs::read_to_string("./src/core/pgpwords.json").unwrap();
let word_map: HashMap<String, Vec<String>> = serde_json::from_str(&json).unwrap();
let mut even_words: Vec<String> = vec![];
let mut odd_words: Vec<String> = vec![];
for (_idx, words) in word_map {
even_words.push(words[0].to_lowercase());
odd_words.push(words[1].to_lowercase());
}
let words = vec![even_words, odd_words];

PgpWordList {
words: words.clone(),
num_words: words.len(),
}
}
}

#[allow(dead_code)] // TODO make this API public one day
pub fn get_completions(&self, prefix: &str) -> Vec<String> {
let count_dashes = prefix.matches('-').count();
impl Completion for PgpWordList {
fn get(&self, input: &str) -> Option<String> {
let count_dashes = input.matches('-').count();
let mut completions = Vec::new();
let words = &self.words[count_dashes % self.words.len()];

let last_partial_word = prefix.split('-').last();
let last_partial_word = input.split('-').last();
let lp = if let Some(w) = last_partial_word {
w.len()
} else {
0
};

for word in words {
let mut suffix: String = prefix.to_owned();
let mut suffix: String = input.to_owned();
if word.starts_with(last_partial_word.unwrap()) {
if lp == 0 {
suffix.push_str(&word);
} else {
let p = prefix.len() - lp;
let p = input.len() - lp;
suffix.truncate(p as usize);
suffix.push_str(&word);
}
Expand All @@ -51,21 +76,15 @@ impl Wordlist {
completions.push(suffix);
}
}
completions.sort();
completions
}

pub fn choose_words(&self) -> String {
let mut rng = OsRng;
let components: Vec<String>;
components = self
.words
.iter()
.cycle()
.take(self.num_words)
.map(|words| words.choose(&mut rng).unwrap().to_string())
.collect();
components.join("-")
if completions.len() == 1 {
Some(completions.first().unwrap().clone())
} else if completions.len() == 0 {
None
} else {
// TODO: show vector of suggestions somehow
// println!("Suggestions: {:#?}", &completions);
None
}
}
}

Expand Down Expand Up @@ -97,8 +116,8 @@ fn load_pgpwords() -> Vec<Vec<String>> {
vec![even_words, odd_words]
}

pub fn default_wordlist(num_words: usize) -> Wordlist {
Wordlist {
pub fn default_wordlist(num_words: usize) -> PgpWordList {
PgpWordList {
num_words,
words: load_pgpwords(),
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ pub mod uri;

pub use crate::core::{
key::{GenericKey, Key, KeyPurpose, WormholeKey},
rendezvous, AppConfig, AppID, Code, Wormhole, WormholeError, WormholeWelcome,
rendezvous,
wordlist::PgpWordList,
AppConfig, AppID, Code, Wormhole, WormholeError, WormholeWelcome,
};

0 comments on commit 528dac8

Please sign in to comment.