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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
use lazy_static::lazy_static; use rand::seq::SliceRandom; use serde::Deserialize; use std::{convert, fmt}; use crate::Item; #[derive(Debug, Deserialize)] struct FirstName { male: Vec<Item>, female: Vec<Item>, } #[derive(Debug, Deserialize)] struct Data { first_name: FirstName, last_name: Vec<Item>, } lazy_static! { static ref DATA: Data = serde_yaml::from_str(include_str!("data/names.yml")).unwrap(); } #[derive(Clone, Debug, PartialEq, Eq)] pub enum Gender { Male, Female, } impl fmt::Display for Gender { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Gender::Male => write!(f, "男"), Gender::Female => write!(f, "女"), } } } #[derive(Debug)] struct MaleName { first: Item, last: Item, } impl rand::distributions::Distribution<MaleName> for rand::distributions::Standard { fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> MaleName { MaleName { first: DATA.first_name.male.choose(rng).cloned().unwrap(), last: DATA.last_name.choose(rng).cloned().unwrap(), } } } #[derive(Debug)] struct FemaleName { first: Item, last: Item, } impl rand::distributions::Distribution<FemaleName> for rand::distributions::Standard { fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> FemaleName { FemaleName { first: DATA.first_name.female.choose(rng).cloned().unwrap(), last: DATA.last_name.choose(rng).cloned().unwrap(), } } } #[derive(Clone, Debug)] pub struct Name { pub first: Item, pub last: Item, pub gender: Gender, } impl Name { pub fn to_kanji(&self) -> String { format!("{} {}", self.last.kanji, self.first.kanji) } pub fn to_hiragana(&self) -> String { format!("{} {}", self.last.hiragana, self.first.hiragana) } pub fn to_katakana(&self) -> String { format!("{} {}", self.last.katakana, self.first.katakana) } pub fn is_male(&self) -> bool { self.gender == Gender::Male } pub fn is_female(&self) -> bool { self.gender == Gender::Female } } impl convert::From<MaleName> for Name { fn from(name: MaleName) -> Self { Self { first: name.first, last: name.last, gender: Gender::Male, } } } impl convert::From<FemaleName> for Name { fn from(name: FemaleName) -> Self { Self { first: name.first, last: name.last, gender: Gender::Female, } } } impl fmt::Display for Name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.to_kanji()) } } pub fn male() -> Name { rand::random::<MaleName>().into() } pub fn female() -> Name { rand::random::<FemaleName>().into() } pub fn name() -> Name { if rand::random() { male() } else { female() } }