rquickjs_extra_sqlite/
argument.rs1use rquickjs::{Ctx, Exception, FromJs, Result, TypedArray};
2use rquickjs_extra_utils::ffi::{CString, CVec};
3use rquickjs_extra_utils::result::ResultExt;
4use sqlx::query::Query;
5use sqlx::sqlite::SqliteArguments;
6use sqlx::Sqlite;
7
8#[derive(Debug)]
9pub enum Argument<'js> {
10 Null,
11 Integer(i64),
12 Real(f64),
13 Text(CString<'js>),
14 Blob(CVec<'js>),
15}
16
17impl<'js> FromJs<'js> for Argument<'js> {
18 fn from_js(ctx: &Ctx<'js>, value: rquickjs::Value<'js>) -> Result<Self> {
19 if value.is_undefined() || value.is_null() {
20 return Ok(Argument::Null);
21 } else if let Some(int) = value.as_int() {
22 return Ok(Argument::Integer(int as i64));
23 } else if let Some(big_int) = value.as_big_int() {
24 return Ok(Argument::Integer(big_int.clone().to_i64()?));
25 } else if let Some(float) = value.as_float() {
26 return Ok(Argument::Real(float));
27 } else if let Some(string) = value.as_string() {
28 return Ok(Argument::Text(CString::from_string(string.clone())?));
29 } else if let Some(object) = value.as_object() {
30 if object.as_typed_array::<u8>().is_some() {
31 return Ok(Argument::Blob(CVec::from_array(
33 TypedArray::<u8>::from_value(value.clone()).or_throw(ctx)?,
34 )?));
35 }
36 }
37 Err(Exception::throw_type(
38 ctx,
39 &["Value of type '", value.type_name(), "' is not supported"].concat(),
40 ))
41 }
42}
43
44impl<'js> Argument<'js> {
45 pub fn try_bind<'q>(
46 &'q self,
47 ctx: &Ctx<'js>,
48 query: &mut Query<'q, Sqlite, SqliteArguments<'q>>,
49 ) -> Result<()>
50 where
51 'js: 'q,
52 {
53 match self {
54 Argument::Null => query.try_bind::<Option<i32>>(None).or_throw(ctx),
55 Argument::Integer(int) => query.try_bind(*int).or_throw(ctx),
56 Argument::Real(float) => query.try_bind(*float).or_throw(ctx),
57 Argument::Text(string) => query.try_bind(string.as_str()?).or_throw(ctx),
58 Argument::Blob(blob) => query.try_bind(blob.as_slice()).or_throw(ctx),
59 }
60 }
61}