From c01f39aefb842a38401d511a43b301dcf8ea73ae Mon Sep 17 00:00:00 2001 From: Piotr Jastrzebski Date: Sun, 7 Jul 2024 18:51:44 +0200 Subject: [PATCH] Make it possible to get row values as &str This allows to avoid some unneeded copies and allocations. Signed-off-by: Piotr Jastrzebski --- core/lib.rs | 6 +++--- core/types.rs | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/core/lib.rs b/core/lib.rs index 39de5871b..9f54d4d83 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -65,12 +65,12 @@ impl Database { loop { match rows.next()? { RowResult::Row(row) => { - let ty = row.get::(0)?; + let ty = row.get::<&str>(0)?; if ty != "table" { continue; } let root_page: i64 = row.get::(3)?; - let sql: String = row.get::(4)?; + let sql: &str = row.get::<&str>(4)?; let table = schema::BTreeTable::from_sql(&sql, root_page as usize)?; schema.add_table(Rc::new(table)); } @@ -242,7 +242,7 @@ pub struct Row<'a> { } impl<'a> Row<'a> { - pub fn get(&self, idx: usize) -> Result { + pub fn get + 'a>(&self, idx: usize) -> Result { let value = &self.values[idx]; T::from_value(value) } diff --git a/core/types.rs b/core/types.rs index f48449953..4bfce889c 100644 --- a/core/types.rs +++ b/core/types.rs @@ -165,14 +165,14 @@ pub fn to_value(value: &OwnedValue) -> Value<'_> { } } -pub trait FromValue { - fn from_value(value: &Value) -> Result +pub trait FromValue<'a> { + fn from_value(value: &Value<'a>) -> Result where - Self: Sized; + Self: Sized + 'a; } -impl FromValue for i64 { - fn from_value(value: &Value) -> Result { +impl<'a> FromValue<'a> for i64 { + fn from_value(value: &Value<'a>) -> Result { match value { Value::Integer(i) => Ok(*i), _ => anyhow::bail!("Expected integer value"), @@ -180,8 +180,8 @@ impl FromValue for i64 { } } -impl FromValue for String { - fn from_value(value: &Value) -> Result { +impl<'a> FromValue<'a> for String { + fn from_value(value: &Value<'a>) -> Result { match value { Value::Text(s) => Ok(s.to_string()), _ => anyhow::bail!("Expected text value"), @@ -189,6 +189,15 @@ impl FromValue for String { } } +impl<'a> FromValue<'a> for &'a str { + fn from_value(value: &Value<'a>) -> Result<&'a str> { + match value { + Value::Text(s) => Ok(&s), + _ => anyhow::bail!("Expected text value"), + } + } +} + #[derive(Debug)] pub struct Record<'a> { pub values: Vec>,