From 4ec30e412a970d572f5149933402e6c5acd7bb67 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 26 Mar 2020 14:42:43 +1000 Subject: [PATCH] newtype NoteID --- rslib/src/notes.rs | 5 ++++- rslib/src/notetypes.rs | 6 ++++-- rslib/src/types.rs | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/rslib/src/notes.rs b/rslib/src/notes.rs index ffe047f4e..68279b3a1 100644 --- a/rslib/src/notes.rs +++ b/rslib/src/notes.rs @@ -7,15 +7,18 @@ use crate::err::{AnkiError, DBErrorKind, Result}; use crate::text::strip_html_preserving_image_filenames; use crate::timestamp::TimestampSecs; use crate::{ + define_newtype, notetypes::NoteType, types::{ObjID, Usn}, }; use rusqlite::{params, Connection, Row, NO_PARAMS}; use std::convert::TryInto; +define_newtype!(NoteID, i64); + #[derive(Debug)] pub(super) struct Note { - pub id: ObjID, + pub id: NoteID, pub mid: ObjID, pub mtime: TimestampSecs, pub usn: Usn, diff --git a/rslib/src/notetypes.rs b/rslib/src/notetypes.rs index 4b9295939..9324c8be3 100644 --- a/rslib/src/notetypes.rs +++ b/rslib/src/notetypes.rs @@ -1,14 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::types::ObjID; +use crate::define_newtype; use serde_aux::field_attributes::deserialize_number_from_string; use serde_derive::Deserialize; +define_newtype!(NoteTypeID, i64); + #[derive(Deserialize, Debug)] pub(crate) struct NoteType { #[serde(deserialize_with = "deserialize_number_from_string")] - pub id: ObjID, + pub id: NoteTypeID, pub name: String, #[serde(rename = "sortf")] pub sort_field_idx: u16, diff --git a/rslib/src/types.rs b/rslib/src/types.rs index 1d3fef25a..760d5a3e8 100644 --- a/rslib/src/types.rs +++ b/rslib/src/types.rs @@ -7,9 +7,23 @@ pub type ObjID = i64; macro_rules! define_newtype { ( $name:ident, $type:ident ) => { #[repr(transparent)] - #[derive(Debug, Clone, Copy)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, + serde::Serialize, serde::Deserialize)] pub struct $name(pub $type); + impl std::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + + impl std::str::FromStr for $name { + type Err = std::num::ParseIntError; + fn from_str(s: &std::primitive::str) -> std::result::Result { + $type::from_str(s).map(|n| $name(n)) + } + } + impl rusqlite::types::FromSql for $name { fn column_result( value: rusqlite::types::ValueRef<'_>,