mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Make AnkiError::SearchError work with ParseError
Use mock ftl strings for now.
This commit is contained in:
parent
4afb476f04
commit
0b73110f82
3 changed files with 92 additions and 15 deletions
|
@ -1,4 +1,38 @@
|
||||||
|
## Errors shown when invalid search input is encountered.
|
||||||
|
|
||||||
search-invalid = Invalid search - please check for typing mistakes.
|
search-invalid = Invalid search - please check for typing mistakes.
|
||||||
|
# The literal string `AND` is part of the search syntax.
|
||||||
|
search-misplaced-and = An `AND` was found but it is not connecting two
|
||||||
|
search terms. If you want to search for the word itself, wrap it in
|
||||||
|
double quotes: "and".
|
||||||
|
# The literal string `OR` is part of the search syntax.
|
||||||
|
search-misplaced-or = An `OR` was found but it is not connecting two
|
||||||
|
search terms. If you want to search for the word itself, wrap it in
|
||||||
|
double quotes: "or".
|
||||||
|
search-empty-group = A group was found but there was nothing between the
|
||||||
|
parentheses to search for.
|
||||||
|
search-empty-quote = A quote was found but there was nothing between the
|
||||||
|
double quotes to search for.
|
||||||
|
search-unclosed-quote = An opening double quote `"` was found but there
|
||||||
|
is no second one to close it.
|
||||||
|
search-missing-key = A colon `:` must be preceded by a key.
|
||||||
|
search-unknown-escape = The escape sequence `` is unknown.
|
||||||
|
search-invalid-id-list = error
|
||||||
|
search-invalid-state = error
|
||||||
|
search-invalid-flag = error
|
||||||
|
search-invalid-added = error
|
||||||
|
search-invalid-edited = error
|
||||||
|
search-invalid-rated-days = error
|
||||||
|
search-invalid-rated-ease = error
|
||||||
|
search-invalid-dupe-mid = error
|
||||||
|
search-invalid-dupe-text = error
|
||||||
|
search-invalid-prop-property = error
|
||||||
|
search-invalid-prop-operator = error
|
||||||
|
search-invalid-prop-float = error
|
||||||
|
search-invalid-prop-integer = error
|
||||||
|
search-invalid-prop-unsigned = error
|
||||||
|
search-invalid-did = error
|
||||||
|
search-invalid-mid = error
|
||||||
|
|
||||||
## Column labels in browse screen
|
## Column labels in browse screen
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub enum AnkiError {
|
||||||
DeckIsFiltered,
|
DeckIsFiltered,
|
||||||
|
|
||||||
#[fail(display = "Invalid search.")]
|
#[fail(display = "Invalid search.")]
|
||||||
SearchError(Option<String>),
|
SearchError(ParseErrorKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
// error helpers
|
// error helpers
|
||||||
|
@ -120,13 +120,38 @@ impl AnkiError {
|
||||||
DBErrorKind::Locked => "Anki already open, or media currently syncing.".into(),
|
DBErrorKind::Locked => "Anki already open, or media currently syncing.".into(),
|
||||||
_ => format!("{:?}", self),
|
_ => format!("{:?}", self),
|
||||||
},
|
},
|
||||||
AnkiError::SearchError(details) => {
|
AnkiError::SearchError(kind) => { match kind {
|
||||||
if let Some(details) = details {
|
ParseErrorKind::MisplacedAnd => i18n.tr(TR::SearchMisplacedAnd),
|
||||||
details.to_owned()
|
ParseErrorKind::MisplacedOr => i18n.tr(TR::SearchMisplacedOr),
|
||||||
|
ParseErrorKind::EmptyGroup => i18n.tr(TR::SearchEmptyGroup),
|
||||||
|
ParseErrorKind::EmptyQuote => i18n.tr(TR::SearchEmptyQuote),
|
||||||
|
ParseErrorKind::UnclosedQuote => i18n.tr(TR::SearchUnclosedQuote),
|
||||||
|
ParseErrorKind::MissingKey => i18n.tr(TR::SearchMissingKey),
|
||||||
|
ParseErrorKind::UnknownEscape(_seq) => i18n.tr(TR::SearchUnknownEscape),
|
||||||
|
ParseErrorKind::InvalidIdList => i18n.tr(TR::SearchInvalidIdList),
|
||||||
|
ParseErrorKind::InvalidState => i18n.tr(TR::SearchInvalidState),
|
||||||
|
ParseErrorKind::InvalidFlag => i18n.tr(TR::SearchInvalidFlag),
|
||||||
|
ParseErrorKind::InvalidAdded => i18n.tr(TR::SearchInvalidAdded),
|
||||||
|
ParseErrorKind::InvalidEdited => i18n.tr(TR::SearchInvalidEdited),
|
||||||
|
ParseErrorKind::InvalidRatedDays => i18n.tr(TR::SearchInvalidRatedDays),
|
||||||
|
ParseErrorKind::InvalidRatedEase => i18n.tr(TR::SearchInvalidRatedEase),
|
||||||
|
ParseErrorKind::InvalidDupeMid => i18n.tr(TR::SearchInvalidDupeMid),
|
||||||
|
ParseErrorKind::InvalidDupeText => i18n.tr(TR::SearchInvalidDupeText),
|
||||||
|
ParseErrorKind::InvalidPropProperty => i18n.tr(TR::SearchInvalidPropProperty),
|
||||||
|
ParseErrorKind::InvalidPropOperator => i18n.tr(TR::SearchInvalidPropOperator),
|
||||||
|
ParseErrorKind::InvalidPropFloat => i18n.tr(TR::SearchInvalidPropFloat),
|
||||||
|
ParseErrorKind::InvalidPropInteger => i18n.tr(TR::SearchInvalidPropInteger),
|
||||||
|
ParseErrorKind::InvalidPropUnsigned => i18n.tr(TR::SearchInvalidPropUnsigned),
|
||||||
|
ParseErrorKind::InvalidDid => i18n.tr(TR::SearchInvalidDid),
|
||||||
|
ParseErrorKind::InvalidMid => i18n.tr(TR::SearchInvalidMid),
|
||||||
|
ParseErrorKind::Regex(text) => text.into(),
|
||||||
|
ParseErrorKind::Other(opt) => if let Some(info) = opt {
|
||||||
|
info.into()
|
||||||
} else {
|
} else {
|
||||||
i18n.tr(TR::SearchInvalid).to_string()
|
i18n.tr(TR::SearchInvalid)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}.into()
|
||||||
|
},
|
||||||
_ => format!("{:?}", self),
|
_ => format!("{:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +189,7 @@ impl From<rusqlite::Error> for AnkiError {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if reason.contains("regex parse error") {
|
if reason.contains("regex parse error") {
|
||||||
return AnkiError::SearchError(Some(reason.to_owned()));
|
return AnkiError::SearchError(ParseErrorKind::Regex(reason.to_owned()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnkiError::DBError {
|
AnkiError::DBError {
|
||||||
|
@ -351,8 +376,8 @@ pub enum ParseErrorKind {
|
||||||
InvalidEdited,
|
InvalidEdited,
|
||||||
InvalidRatedDays,
|
InvalidRatedDays,
|
||||||
InvalidRatedEase,
|
InvalidRatedEase,
|
||||||
InvalidDupesMid,
|
InvalidDupeMid,
|
||||||
InvalidDupesText,
|
InvalidDupeText,
|
||||||
InvalidPropProperty,
|
InvalidPropProperty,
|
||||||
InvalidPropOperator,
|
InvalidPropOperator,
|
||||||
InvalidPropFloat,
|
InvalidPropFloat,
|
||||||
|
@ -360,6 +385,27 @@ pub enum ParseErrorKind {
|
||||||
InvalidPropUnsigned,
|
InvalidPropUnsigned,
|
||||||
InvalidDid,
|
InvalidDid,
|
||||||
InvalidMid,
|
InvalidMid,
|
||||||
|
Regex(String),
|
||||||
|
Other(Option<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseError<'_>> for AnkiError {
|
||||||
|
fn from(err: ParseError) -> Self {
|
||||||
|
match err {
|
||||||
|
ParseError::Anki(_, kind) => AnkiError::SearchError(kind),
|
||||||
|
ParseError::Nom(_, _) => AnkiError::SearchError(ParseErrorKind::Other(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<nom::Err<ParseError<'_>>> for AnkiError {
|
||||||
|
fn from(err: nom::Err<ParseError<'_>>) -> Self {
|
||||||
|
match err {
|
||||||
|
nom::Err::Error(e) => e.into(),
|
||||||
|
nom::Err::Failure(e) => e.into(),
|
||||||
|
nom::Err::Incomplete(_) => AnkiError::SearchError(ParseErrorKind::Other(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NomParseError<&'a str> for ParseError<'a> {
|
impl<'a> NomParseError<&'a str> for ParseError<'a> {
|
||||||
|
|
|
@ -110,10 +110,7 @@ pub(super) fn parse(input: &str) -> Result<Vec<Node>> {
|
||||||
return Ok(vec![Node::Search(SearchNode::WholeCollection)]);
|
return Ok(vec![Node::Search(SearchNode::WholeCollection)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, nodes) = all_consuming(group_inner)(input).map_err(|e| {
|
let (_, nodes) = all_consuming(group_inner)(input)?;
|
||||||
dbg!(e);
|
|
||||||
AnkiError::SearchError(None)
|
|
||||||
})?;
|
|
||||||
Ok(nodes)
|
Ok(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue