123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- use rand::seq::SliceRandom;
- use sauron::html::attributes::{class, id};
- use sauron::html::events::on_click;
- use sauron::html::{div, text};
- use sauron::prelude::*;
- use sauron::{Cmd, Component, Node, Program};
-
- mod tlds;
-
- pub enum Msg {
- Click,
- ReceivedWords(Result<Vec<String>, JsValue>),
- }
-
- pub struct App {
- output: Option<String>,
- words: Vec<String>,
- }
-
- impl App {
- pub fn new() -> Self {
- App {
- output: None,
- words: vec![],
- }
- }
-
- fn generate_domain(&mut self) -> String {
- let mut domain: String = String::from("");
-
- while domain.is_empty() {
- let tld = self.get_random_tld();
- tld.map(|tld| {
- let word = self.get_random_word(&tld);
- if word.is_some() {
- let mut word = word.unwrap();
- word.truncate(word.len() - 2);
- domain = format!("{}.{}", word, tld);
- }
- });
- }
-
- domain
- }
-
- fn get_random_tld(&mut self) -> Option<String> {
- crate::tlds::tlds()
- .choose(&mut rand::thread_rng())
- .map(|v| String::from(v))
- }
-
- fn get_random_word(&self, tld: &str) -> Option<String> {
- self.words
- .clone()
- .into_iter()
- .filter(|word| word.ends_with(tld))
- .collect::<Vec<String>>()
- .choose(&mut rand::thread_rng())
- .map(|v| v.to_string().to_lowercase())
- }
- }
-
- impl Component<Msg> for App {
- fn init(&self) -> Cmd<Self, Msg> {
- Http::fetch_with_text_response_decoder(
- "/words.txt",
- |r: String| r.lines().map(|l| l.to_string()).collect(),
- Msg::ReceivedWords,
- )
- }
-
- fn view(&self) -> Node<Msg> {
- let output = match &self.output {
- Some(s) => vec![text(s)],
- None => vec![],
- };
-
- let loading = self.words.len() == 0;
-
- sauron::html::main(
- vec![],
- vec![div(
- vec![class("container")],
- vec![
- h1(vec![class("heading")], vec![text("Domain Hack Generator")]),
- div(
- vec![class("button-container")],
- vec![
- button(
- vec![
- class("button"),
- disabled(loading),
- on_click(|_: MouseEvent| Msg::Click),
- ],
- vec![text(if loading { "Loading..." } else { "Generate" })],
- ),
- p(vec![id("result")], output),
- ],
- ),
- ],
- )],
- )
- }
-
- fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> {
- match msg {
- Msg::Click => self.output = Some(self.generate_domain()),
- Msg::ReceivedWords(result) => match result {
- Ok(words) => self.words = words,
- Err(_) => {}
- },
- }
- Cmd::none()
- }
- }
-
- #[wasm_bindgen(start)]
- pub fn main() {
- console_log::init_with_level(log::Level::Trace).unwrap();
- console_error_panic_hook::set_once();
- Program::mount_to_body(App::new());
- }
|