Merge pull request #1069 from Arthur-Milchior/Emptying_field_lead_to_proper_message

Emptying field lead to proper message
This commit is contained in:
Damien Elmes 2021-03-15 13:17:05 +10:00 committed by GitHub
commit 5ff5a6f2e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 23 deletions

View file

@ -1,7 +1,10 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::backend_proto::{NoteField as NoteFieldProto, NoteFieldConfig, OptionalUInt32}; use crate::{
backend_proto::{NoteField as NoteFieldProto, NoteFieldConfig, OptionalUInt32},
err::{AnkiError, Result},
};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct NoteField { pub struct NoteField {
@ -35,8 +38,11 @@ impl NoteField {
} }
} }
pub(crate) fn fix_name(&mut self) { /// Fix the name of the field if it's valid. Otherwise explain why it's not.
// remove special characters pub(crate) fn fix_name(&mut self) -> Result<()> {
if self.name.is_empty() {
return Err(AnkiError::invalid_input("Empty field name"));
}
let bad_chars = |c| c == ':' || c == '{' || c == '}' || c == '"'; let bad_chars = |c| c == ':' || c == '{' || c == '}' || c == '"';
if self.name.contains(bad_chars) { if self.name.contains(bad_chars) {
self.name = self.name.replace(bad_chars, ""); self.name = self.name.replace(bad_chars, "");
@ -44,9 +50,15 @@ impl NoteField {
// and leading/trailing whitespace and special chars // and leading/trailing whitespace and special chars
let bad_start_chars = |c: char| c == '#' || c == '/' || c == '^' || c.is_whitespace(); let bad_start_chars = |c: char| c == '#' || c == '/' || c == '^' || c.is_whitespace();
let trimmed = self.name.trim().trim_start_matches(bad_start_chars); let trimmed = self.name.trim().trim_start_matches(bad_start_chars);
if trimmed.is_empty() {
return Err(AnkiError::invalid_input(
"Field name: ".to_owned() + &self.name,
));
}
if trimmed.len() != self.name.len() { if trimmed.len() != self.name.len() {
self.name = trimmed.into(); self.name = trimmed.into();
} }
Ok(())
} }
} }
@ -57,7 +69,7 @@ mod test {
#[test] #[test]
fn name() { fn name() {
let mut field = NoteField::new(" # /^ t:e{s\"t} field name #/^ "); let mut field = NoteField::new(" # /^ t:e{s\"t} field name #/^ ");
field.fix_name(); assert_eq!(field.fix_name(), Ok(()));
assert_eq!(&field.name, "test field name #/^"); assert_eq!(&field.name, "test field name #/^");
} }
} }

View file

@ -329,25 +329,13 @@ impl NoteType {
} }
fn fix_field_names(&mut self) -> Result<()> { fn fix_field_names(&mut self) -> Result<()> {
for mut f in &mut self.fields { self.fields.iter_mut().try_for_each(NoteField::fix_name)
NoteField::fix_name(&mut f);
if f.name.is_empty() {
return Err(AnkiError::invalid_input("Empty field name"));
}
}
Ok(())
} }
fn fix_template_names(&mut self) -> Result<()> { fn fix_template_names(&mut self) -> Result<()> {
for mut t in &mut self.templates { self.templates
CardTemplate::fix_name(&mut t); .iter_mut()
if t.name.is_empty() { .try_for_each(CardTemplate::fix_name)
return Err(AnkiError::invalid_input("Empty template name"));
}
}
Ok(())
} }
/// Find the field index of the provided field name. /// Find the field index of the provided field name.

View file

@ -4,6 +4,7 @@
use crate::{ use crate::{
backend_proto::{CardTemplate as CardTemplateProto, CardTemplateConfig, OptionalUInt32}, backend_proto::{CardTemplate as CardTemplateProto, CardTemplateConfig, OptionalUInt32},
decks::DeckID, decks::DeckID,
err::{AnkiError, Result},
template::ParsedTemplate, template::ParsedTemplate,
timestamp::TimestampSecs, timestamp::TimestampSecs,
types::Usn, types::Usn,
@ -89,10 +90,21 @@ impl CardTemplate {
} }
} }
pub(crate) fn fix_name(&mut self) { /// Return whether the name is valid. Remove quote characters if it leads to a valid name.
pub(crate) fn fix_name(&mut self) -> Result<()> {
let bad_chars = |c| c == '"'; let bad_chars = |c| c == '"';
if self.name.contains(bad_chars) { if self.name.is_empty() {
self.name = self.name.replace(bad_chars, ""); return Err(AnkiError::invalid_input("Empty template name"));
} }
let trimmed = self.name.replace(bad_chars, "");
if trimmed.is_empty() {
return Err(AnkiError::invalid_input(
"Template name contain only quotes",
));
}
if self.name.len() != trimmed.len() {
self.name = trimmed;
}
Ok(())
} }
} }