Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/Sort Tenses #7

Merged
merged 2 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading