Skip to content

Commit

Permalink
Feat/Sort Tenses (#7)
Browse files Browse the repository at this point in the history
* feat(app): sort verb tenses by mood and tense

* chore(app): remove deprecated graphql query
  • Loading branch information
cobbinma authored Apr 28, 2024
1 parent 8f25557 commit c5590d7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 60 deletions.
138 changes: 88 additions & 50 deletions conjugation-api/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fmt::Display, str::FromStr};
use std::{cmp::Ordering, fmt::Display, str::FromStr};

use juniper::{http::graphiql, http::GraphQLRequest, EmptyMutation, EmptySubscription, RootNode};
use lazy_static::lazy_static;
Expand All @@ -7,7 +7,7 @@ use tide::{http::mime, Body, Redirect, Request, Response, Server, StatusCode};

const DB_URL: &str = "sqlite://data/verbs.db";

#[derive(Clone, juniper::GraphQLEnum)]
#[derive(Clone, juniper::GraphQLEnum, PartialEq, Eq)]
enum Tense {
Presente,
Preterito,
Expand Down Expand Up @@ -58,7 +58,48 @@ impl FromStr for Tense {
}
}

#[derive(Clone, juniper::GraphQLEnum)]
impl PartialOrd for Tense {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Tense {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Tense::Presente, Tense::Presente) => Ordering::Equal,
(Tense::Presente, _) => Ordering::Less,
(_, Tense::Presente) => Ordering::Greater,
(Tense::Imperfecto, Tense::Imperfecto) => Ordering::Equal,
(Tense::Imperfecto, _) => Ordering::Less,
(_, Tense::Imperfecto) => Ordering::Greater,
(Tense::Preterito, Tense::Preterito) => Ordering::Equal,
(Tense::Preterito, _) => Ordering::Less,
(_, Tense::Preterito) => Ordering::Greater,
(Tense::Futuro, Tense::Futuro) => Ordering::Equal,
(Tense::Futuro, _) => Ordering::Less,
(_, Tense::Futuro) => Ordering::Greater,
(Tense::Condicional, Tense::Condicional) => Ordering::Equal,
(Tense::Condicional, _) => Ordering::Less,
(_, Tense::Condicional) => Ordering::Greater,
(Tense::PresentePerfecto, Tense::PresentePerfecto) => Ordering::Equal,
(Tense::PresentePerfecto, _) => Ordering::Less,
(_, Tense::PresentePerfecto) => Ordering::Greater,
(Tense::Pluscuamperfecto, Tense::Pluscuamperfecto) => Ordering::Equal,
(Tense::Pluscuamperfecto, _) => Ordering::Less,
(_, Tense::Pluscuamperfecto) => Ordering::Greater,
(Tense::PreteritoAnterior, Tense::PreteritoAnterior) => Ordering::Equal,
(Tense::PreteritoAnterior, _) => Ordering::Less,
(_, Tense::PreteritoAnterior) => Ordering::Greater,
(Tense::FuturoPerfecto, Tense::FuturoPerfecto) => Ordering::Equal,
(Tense::FuturoPerfecto, _) => Ordering::Less,
(_, Tense::FuturoPerfecto) => Ordering::Greater,
(Tense::CondicionalPerfecto, Tense::CondicionalPerfecto) => Ordering::Equal,
}
}
}

#[derive(Clone, juniper::GraphQLEnum, PartialEq, Eq)]
enum Mood {
Indicativo,
Subjuntivo,
Expand Down Expand Up @@ -91,7 +132,30 @@ impl FromStr for Mood {
}
}

#[derive(Clone, juniper::GraphQLEnum)]
impl PartialOrd for Mood {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Mood {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Mood::Indicativo, Mood::Indicativo) => Ordering::Equal,
(Mood::Indicativo, _) => Ordering::Less,
(_, Mood::Indicativo) => Ordering::Greater,
(Mood::Subjuntivo, Mood::Subjuntivo) => Ordering::Equal,
(Mood::Subjuntivo, _) => Ordering::Less,
(_, Mood::Subjuntivo) => Ordering::Greater,
(Mood::ImperativoAfirmativo, Mood::ImperativoAfirmativo) => Ordering::Equal,
(Mood::ImperativoAfirmativo, _) => Ordering::Less,
(_, Mood::ImperativoAfirmativo) => Ordering::Greater,
(Mood::ImperativoNegativo, Mood::ImperativoNegativo) => Ordering::Equal,
}
}
}

#[derive(Clone, juniper::GraphQLEnum, PartialEq, Eq)]
enum Pronoun {
Yo,
Tu,
Expand All @@ -101,7 +165,7 @@ enum Pronoun {
Ellos,
}

#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
struct Conjugation {
pronoun: Pronoun,
spanish: String,
Expand Down Expand Up @@ -130,7 +194,7 @@ struct Verb {
tenses: Vec<VerbTense>,
}

#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
struct VerbTense {
infinitive: String,
verb_english: Option<String>,
Expand All @@ -139,6 +203,22 @@ struct VerbTense {
conjugations: Vec<Conjugation>,
}

impl Ord for VerbTense {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
if self.mood == other.mood {
self.tense.cmp(&other.tense)
} else {
self.mood.cmp(&other.mood)
}
}
}

impl PartialOrd for VerbTense {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl From<RepositoryConjugations> for VerbTense {
fn from(value: RepositoryConjugations) -> Self {
let RepositoryConjugations {
Expand Down Expand Up @@ -361,13 +441,14 @@ impl QueryRoot {

let query = query_builder.build_query_as::<RepositoryConjugations>();

let tenses: Vec<VerbTense> = query
let mut tenses: Vec<VerbTense> = query
.fetch_all(&context.pool)
.await
.unwrap_or_default()
.into_iter()
.map(VerbTense::from)
.collect();
tenses.sort();

Some(Verb {
infinitive: inf,
Expand All @@ -377,49 +458,6 @@ impl QueryRoot {
tenses,
})
}

#[graphql(description = "get a conjugated verb")]
async fn verb_tense(
context: &State,
infinitive: Option<String>,
tenses: Option<Vec<Tense>>,
) -> Option<VerbTense> {
let mut query_builder: QueryBuilder<Sqlite> =
QueryBuilder::new("SELECT infinitive, tense, mood, verb_english, form_1s, form_2s, form_3s, form_1p, form_2p, form_3p FROM verbs WHERE mood = 'Indicativo'");

if let Some(infinitive) = infinitive {
query_builder.push(" AND infinitive = ");
query_builder.push_bind(infinitive);
};

let tenses = match tenses {
Some(tenses) if !tenses.is_empty() => tenses,
_ => vec![
Tense::Presente,
Tense::Imperfecto,
Tense::Preterito,
Tense::Futuro,
Tense::PresentePerfecto,
],
};

query_builder.push(" AND tense IN (");
let mut separated = query_builder.separated(", ");
for tense in tenses.iter() {
separated.push_bind(tense.to_string());
}
separated.push_unseparated(")");

query_builder.push(" ORDER BY RANDOM() LIMIT 1");

let query = query_builder.build_query_as::<RepositoryConjugations>();

query
.fetch_optional(&context.pool)
.await
.unwrap_or_default()
.map(VerbTense::from)
}
}

pub type Schema = RootNode<'static, QueryRoot, EmptyMutation<State>, EmptySubscription<State>>;
Expand Down
2 changes: 0 additions & 2 deletions conjugation-ui/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ schema {
type QueryRoot {
"get a verb"
verb(infinitive: String!): Verb
"get a conjugated verb"
verbTense(infinitive: String, tenses: [Tense!]): VerbTense
}
type Verb {
"Infinitive form of the verb"
Expand Down
8 changes: 0 additions & 8 deletions conjugation-ui/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,13 @@ export type QueryRoot = {
__typename?: 'QueryRoot';
/** get a verb */
verb?: Maybe<Verb>;
/** get a conjugated verb */
verbTense?: Maybe<VerbTense>;
};


export type QueryRootVerbArgs = {
infinitive: Scalars['String']['input'];
};


export type QueryRootVerbTenseArgs = {
infinitive?: InputMaybe<Scalars['String']['input']>;
tenses?: InputMaybe<Array<Tense>>;
};

export enum Tense {
Condicional = 'CONDICIONAL',
CondicionalPerfecto = 'CONDICIONAL_PERFECTO',
Expand Down

0 comments on commit c5590d7

Please sign in to comment.