From 9080f602b1c593b1a6c634e62a3db11fdd4f4050 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 14 Apr 2020 09:32:28 +1000 Subject: [PATCH] native struct for NoteField ord is made optional so we can keep track of changes in the future --- proto/backend.proto | 6 +++++- rslib/src/notetype/fields.rs | 36 +++++++++++++++++++++++++++++++ rslib/src/notetype/mod.rs | 14 +++++------- rslib/src/notetype/schema11.rs | 12 ++++++----- rslib/src/search/sqlwriter.rs | 2 +- rslib/src/storage/notetype/mod.rs | 8 +++---- 6 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 rslib/src/notetype/fields.rs diff --git a/proto/backend.proto b/proto/backend.proto index 9af2a3e6f..d2e0fb393 100644 --- a/proto/backend.proto +++ b/proto/backend.proto @@ -10,6 +10,10 @@ message OptionalInt32 { sint32 val = 1; } +message OptionalUInt32 { + uint32 val = 1; +} + message BackendInit { repeated string preferred_langs = 1; string locale_folder_path = 2; @@ -492,7 +496,7 @@ message NoteFieldConfig { } message NoteField { - uint32 ord = 1; + OptionalUInt32 ord = 1; string name = 2; NoteFieldConfig config = 5; } diff --git a/rslib/src/notetype/fields.rs b/rslib/src/notetype/fields.rs new file mode 100644 index 000000000..051d97576 --- /dev/null +++ b/rslib/src/notetype/fields.rs @@ -0,0 +1,36 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +use crate::backend_proto::{NoteField as NoteFieldProto, NoteFieldConfig, OptionalUInt32}; + +pub struct NoteField { + pub ord: Option, + pub name: String, + pub config: NoteFieldConfig, +} + +impl From for NoteFieldProto { + fn from(f: NoteField) -> Self { + NoteFieldProto { + ord: f.ord.map(|n| OptionalUInt32 { val: n }), + name: f.name, + config: Some(f.config), + } + } +} + +impl NoteField { + pub fn new(name: impl Into) -> Self { + NoteField { + ord: None, + name: name.into(), + config: NoteFieldConfig { + sticky: false, + rtl: false, + font_name: "Arial".into(), + font_size: 20, + other: vec![], + }, + } + } +} diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 2f7aa6ed9..2a74d44c9 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -1,13 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +mod fields; mod schema11; mod stock; pub use crate::backend_proto::{ card_requirement::CardRequirementKind, CardRequirement, CardTemplate, CardTemplateConfig, - NoteField, NoteFieldConfig, NoteType as NoteTypeProto, NoteTypeConfig, NoteTypeKind, + NoteFieldConfig, NoteType as NoteTypeProto, NoteTypeConfig, NoteTypeKind, }; +pub use fields::NoteField; pub use schema11::{CardTemplateSchema11, NoteFieldSchema11, NoteTypeSchema11}; pub use stock::all_stock_notetypes; @@ -156,13 +158,7 @@ impl NoteType { } pub(crate) fn add_field>(&mut self, name: S) { - let mut config = NoteFieldConfig::default(); - config.font_name = "Arial".to_string(); - config.font_size = 20; - let mut field = NoteField::default(); - field.name = name.into(); - field.config = Some(config); - self.fields.push(field); + self.fields.push(NoteField::new(name)); } pub(crate) fn add_template(&mut self, name: S1, qfmt: S2, afmt: S3) @@ -197,7 +193,7 @@ impl From for NoteTypeProto { mtime_secs: nt.mtime_secs.0 as u32, usn: nt.usn.0, config: Some(nt.config), - fields: nt.fields, + fields: nt.fields.into_iter().map(Into::into).collect(), templates: nt.templates, } } diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs index 8eabaecbe..2e750301a 100644 --- a/rslib/src/notetype/schema11.rs +++ b/rslib/src/notetype/schema11.rs @@ -222,25 +222,27 @@ impl Default for NoteFieldSchema11 { impl From for NoteField { fn from(f: NoteFieldSchema11) -> Self { NoteField { - ord: f.ord as u32, + ord: Some(f.ord as u32), name: f.name, - config: Some(NoteFieldConfig { + config: NoteFieldConfig { sticky: f.sticky, rtl: f.rtl, font_name: f.font, font_size: f.size as u32, other: other_to_bytes(&f.other), - }), + }, } } } +// fixme: must make sure calling code doesn't break the assumption ord is set + impl From for NoteFieldSchema11 { fn from(p: NoteField) -> Self { - let conf = p.config.unwrap(); + let conf = p.config; NoteFieldSchema11 { name: p.name, - ord: p.ord as u16, + ord: p.ord.unwrap() as u16, sticky: conf.sticky, rtl: conf.rtl, font: conf.font_name, diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index f5ee1c6b1..66c09dc7e 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -333,7 +333,7 @@ impl SqlWriter<'_> { format!( "(n.mid = {mid} and field_at_index(n.flds, {ord}) {cmp} ?{n})", mid = ntid, - ord = ord, + ord = ord.unwrap_or_default(), cmp = cmp, n = arg_idx ) diff --git a/rslib/src/storage/notetype/mod.rs b/rslib/src/storage/notetype/mod.rs index bd87f2590..7477f8fb8 100644 --- a/rslib/src/storage/notetype/mod.rs +++ b/rslib/src/storage/notetype/mod.rs @@ -3,8 +3,8 @@ use super::SqliteStorage; use crate::{ - backend_proto::{CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, NoteTypeConfig}, err::{AnkiError, DBErrorKind, Result}, + notetype::{CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, NoteTypeConfig}, notetype::{NoteType, NoteTypeID, NoteTypeSchema11}, timestamp::TimestampMillis, }; @@ -49,9 +49,9 @@ impl SqliteStorage { .query_and_then(&[ntid], |row| { let config = NoteFieldConfig::decode(row.get_raw(2).as_blob()?)?; Ok(NoteField { - ord: row.get(0)?, + ord: Some(row.get(0)?), name: row.get(1)?, - config: Some(config), + config, }) })? .collect() @@ -110,7 +110,7 @@ impl SqliteStorage { let mut stmt = self.db.prepare_cached(include_str!("update_fields.sql"))?; for (ord, field) in fields.iter().enumerate() { let mut config_bytes = vec![]; - field.config.as_ref().unwrap().encode(&mut config_bytes)?; + field.config.encode(&mut config_bytes)?; stmt.execute(params![ntid, ord as u32, field.name, config_bytes,])?; }