refactor(predlozhnik): use BTreeSet's for the ... sets

The stable ordering guarantee will make the output a lot nicer (and
more stable).

Change-Id: I7edd1abb0805e948bc41fe5bc111b3cb54592aac
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5982
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
Vincent Ambo 2022-07-27 21:58:17 +03:00 committed by tazjin
parent 7b217bbbe1
commit 67b7668e85

View file

@ -2,10 +2,11 @@ use yew::prelude::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use maplit::hashmap; use maplit::hashmap;
use std::collections::BTreeSet;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Write; use std::fmt::Write;
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
enum Падеж { enum Падеж {
Именительный, Именительный,
Родительный, Родительный,
@ -39,55 +40,55 @@ impl Падеж {
} }
lazy_static! { lazy_static! {
static ref ПОРЕДЛОГУ: HashMap<&'static str, Vec<Падеж>> = { static ref ПОРЕДЛОГУ: HashMap<&'static str, BTreeSet<Падеж>> = {
use Падеж::*; use Падеж::*;
hashmap! { hashmap! {
"без" => vec![Родительный], "без" => BTreeSet::from([Родительный]),
"близ" => vec![Родительный], "близ" => BTreeSet::from([Родительный]),
"в" => vec![Винительный, Предложный], "в" => BTreeSet::from([Винительный, Предложный]),
"вместо" => vec![Родительный], "вместо" => BTreeSet::from([Родительный]),
"вне" => vec![Родительный], "вне" => BTreeSet::from([Родительный]),
"возле" => vec![Родительный], "возле" => BTreeSet::from([Родительный]),
"вокруг" => vec![Родительный], "вокруг" => BTreeSet::from([Родительный]),
"вроде" => vec![Родительный], "вроде" => BTreeSet::from([Родительный]),
"для" => vec![Родительный], "для" => BTreeSet::from([Родительный]),
"до" => vec![Родительный], "до" => BTreeSet::from([Родительный]),
"за" => vec![Винительный, Творительный], "за" => BTreeSet::from([Винительный, Творительный]),
"из" => vec![Родительный], "из" => BTreeSet::from([Родительный]),
"из-за" => vec![Родительный], "из-за" => BTreeSet::from([Родительный]),
"из-под" => vec![Родительный], "из-под" => BTreeSet::from([Родительный]),
"к" => vec![Дательный], "к" => BTreeSet::from([Дательный]),
"кроме" => vec![Родительный], "кроме" => BTreeSet::from([Родительный]),
"между" => vec![Творительный, Родительный], "между" => BTreeSet::from([Творительный, Родительный]),
"на" => vec![Винительный, Предложный], "на" => BTreeSet::from([Винительный, Предложный]),
"над" => vec![Творительный], "над" => BTreeSet::from([Творительный]),
"нет" => vec![Именительный], "нет" => BTreeSet::from([Именительный]),
"о" => vec![Винительный], "о" => BTreeSet::from([Винительный]),
"обо" => vec![Винительный], "обо" => BTreeSet::from([Винительный]),
"около" => vec![Родительный], "около" => BTreeSet::from([Родительный]),
"от" => vec![Родительный], "от" => BTreeSet::from([Родительный]),
"перед" => vec![Творительный], "перед" => BTreeSet::from([Творительный]),
"по" => vec![Винительный, Дательный, Предложный], "по" => BTreeSet::from([Винительный, Дательный, Предложный]),
"под" => vec![Винительный, Творительный], "под" => BTreeSet::from([Винительный, Творительный]),
"при" => vec![Предложный], "при" => BTreeSet::from([Предложный]),
"про" => vec![Винительный], "про" => BTreeSet::from([Винительный]),
"ради" => vec![Родительный], "ради" => BTreeSet::from([Родительный]),
"с" => vec![Родительный, Винительный, Творительный], "с" => BTreeSet::from([Родительный, Винительный, Творительный]),
"сквозь" => vec![Винительный], "сквозь" => BTreeSet::from([Винительный]),
"среди" => vec![Родительный], "среди" => BTreeSet::from([Родительный]),
"у" => vec![Родительный], "у" => BTreeSet::from([Родительный]),
"через" => vec![Винительный], "через" => BTreeSet::from([Винительный]),
} }
}; };
static ref ПОАДЕЖУ: HashMap<Падеж, Vec<&'static str>> = { static ref ПОАДЕЖУ: HashMap<Падеж, BTreeSet<&'static str>> = {
let mut m = hashmap!(); let mut m = hashmap!();
for c in Падеж::ВСЕ { for c in Падеж::ВСЕ {
let mut предлоги: Vec<&'static str> = vec![]; let mut предлоги: BTreeSet<&'static str> = BTreeSet::new();
for (k, v) in &*ПОРЕДЛОГУ { for (k, v) in &*ПОРЕДЛОГУ {
if v.contains(&c) { if v.contains(&c) {
предлоги.push(k); предлоги.insert(k);
} }
} }
@ -123,8 +124,8 @@ struct Модель {
} }
struct Вывод { struct Вывод {
доступные_падежи: Vec<Падеж>, доступные_падежи: BTreeSet<Падеж>,
доступные_предлоги: Vec<&'static str>, доступные_предлоги: BTreeSet<&'static str>,
объяснение: Option<Html>, объяснение: Option<Html>,
} }
@ -137,26 +138,26 @@ fn объяснить(падеж: Падеж, предлог: &str) -> Html {
fn ограничить(м: &Модель) -> Вывод { fn ограничить(м: &Модель) -> Вывод {
match (м.падеж, &м.предлог) { match (м.падеж, &м.предлог) {
(Some(пж), Some(пл)) => Вывод { (Some(пж), Some(пл)) => Вывод {
доступные_падежи: vec![пж], доступные_падежи: BTreeSet::from([пж]),
доступные_предлоги: vec![пл], доступные_предлоги: BTreeSet::from([*пл]),
объяснение: Some(объяснить(пж, пл)), объяснение: Some(объяснить(пж, пл)),
}, },
(Some(пж), None) => Вывод { (Some(пж), None) => Вывод {
доступные_падежи: vec![пж], доступные_падежи: BTreeSet::from([пж]),
доступные_предлоги: (*ПОАДЕЖУ)[&пж].clone(), доступные_предлоги: (*ПОАДЕЖУ)[&пж].clone(),
объяснение: None, объяснение: None,
}, },
(None, Some(пл)) => Вывод { (None, Some(пл)) => Вывод {
доступные_падежи: (*ПОРЕДЛОГУ)[пл].clone(), доступные_падежи: (*ПОРЕДЛОГУ)[пл].clone(),
доступные_предлоги: vec![пл], доступные_предлоги: BTreeSet::from([*пл]),
объяснение: None, объяснение: None,
}, },
(None, None) => Вывод { (None, None) => Вывод {
доступные_падежи: vec![], доступные_падежи: BTreeSet::new(),
доступные_предлоги: vec![], доступные_предлоги: BTreeSet::new(),
объяснение: None, объяснение: None,
}, },
} }