Repository: meilisearch/meilisearch
File: milli/src/asc_desc.rs (Rust)

Code before:
//! This module provides the `AscDesc` type and defines all the errors related to this type.

use std::fmt;
use std::str::FromStr;

use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::error::is_reserved_keyword;
use crate::search::facet::ParseGeoError;
use crate::{CriterionError, Error, UserError};

/// This error type is never supposed to be shown to the end user.
/// You must always cast it to a sort error or a criterion error.
#[derive(Debug)]
pub enum AscDescError {
    GeoError(ParseGeoError),
    InvalidSyntax { name: String },
    ReservedKeyword { name: String },
}

impl From<ParseGeoError> for AscDescError {
    fn from(geo_error: ParseGeoError) -> Self {
        AscDescError::GeoError(geo_error)
    }
}

impl fmt::Display for AscDescError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::GeoError(error) => {
                write!(f, "{error}",)
            }
            Self::InvalidSyntax { name } => {
                write!(f, "Invalid syntax for the asc/desc parameter: expected expression ending by `:asc` or `:desc`, found `{}`.", name)
            }
            Self::ReservedKeyword { name } => {
                write!(
                    f,
                    "`{}` is a reserved keyword and thus can't be used as a asc/desc rule.",
                    name
                )

Review comment (suggestion):
Hey, this is not mandatory, if you don't want/don't have the time just tell me and I'll do it later.

But it would be nice to use thiserror on this error structure 

Code after:
//! This module provides the `AscDesc` type and defines all the errors related to this type.

use std::fmt;
use std::str::FromStr;

use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::error::is_reserved_keyword;
use crate::search::facet::BadGeoError;
use crate::{CriterionError, Error, UserError};

/// This error type is never supposed to be shown to the end user.
/// You must always cast it to a sort error or a criterion error.
#[derive(Error, Debug)]
pub enum AscDescError {
    #[error(transparent)]
    GeoError(BadGeoError),
    #[error("Invalid syntax for the asc/desc parameter: expected expression ending by `:asc` or `:desc`, found `{name}`.")]
    InvalidSyntax { name: String },
    #[error("`{name}` is a reserved keyword and thus can't be used as a asc/desc rule.")]
    ReservedKeyword { name: String },
}

impl From<BadGeoError> for AscDescError {
    fn from(geo_error: BadGeoError) -> Self {
        AscDescError::GeoError(geo_error)
    }
}

impl From<AscDescError> for CriterionError {
    fn from(error: AscDescError) -> Self {
        match error {
            AscDescError::GeoError(_) => {
                CriterionError::ReservedNameForSort { name: "_geoPoint".to_string() }
            }
            AscDescError::InvalidSyntax { name } => CriterionError::InvalidName { name },
            AscDescError::ReservedKeyword { name } if name.starts_with("_geoPoint") => {
                CriterionError::ReservedNameForSort { name: "_geoPoint".to_string() }
            }
            AscDescError::ReservedKeyword { name } if name.starts_with("_geoRadius") => {
                CriterionError::ReservedNameForFilter { name: "_geoRadius".to_string() }