Skip to content

Commit

Permalink
add number api
Browse files Browse the repository at this point in the history
  • Loading branch information
SunDoge committed Aug 25, 2023
1 parent 440347a commit 4ef4b84
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 18 deletions.
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
[package]
name = "simdjson-rust"
version = "0.3.0"
version = "0.3.0-alpha"
authors = ["SunDoge <384813529@qq.com>"]
edition = "2021"
license = "Apache-2.0"
description = "Rust bindings for the simdjson project."
homepage = "https://crates.io/crates/simdjson-rust"
documentation = "https://docs.rs/simdjson-rust"
repository = "https://github.com/SunDoge/simdjson-rust"
readme = "README.md"
exclude = [".github/", "examples/"]


Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

This crate currently uses `simdjson 3.2.3`. You can have a try and give feedback.

If you

- find certain APIs are missing
- encounter memory errors
- experience performance degradation

Please submit an issue.

## Usage

Add this to your `Cargo.toml`
Expand All @@ -16,9 +24,9 @@ simdjson-rust = {git = "https://github.com/SunDoge/simdjson-rust"}
Then, get started.

```rust
use simdjson_rust::{error::Result, ondemand::parser::Parser, padded_string::make_padded_string};
use simdjson_rust::{ondemand::Parser, prelude::*};

fn main() -> Result<()> {
fn main() -> simdjson_rust::Result<()> {
let mut parser = Parser::default();
let ps = make_padded_string("[0,1,2,3]");
let mut doc = parser.iterate(&ps)?;
Expand Down
4 changes: 2 additions & 2 deletions examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use simdjson_rust::{ondemand::Parser, prelude::*};
use simdjson_rust::prelude::*;

fn main() -> simdjson_rust::Result<()> {
let mut parser = Parser::default();
let mut parser = ondemand::Parser::default();
let ps = make_padded_string("[0,1,2,3]");
let mut doc = parser.iterate(&ps)?;
let mut array = doc.get_array()?;
Expand Down
38 changes: 35 additions & 3 deletions simdjson-sys/src/simdjson_c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ template <typename U, typename T> inline U object_to_pointer(T &&t) {
return reinterpret_cast<U>(new T(std::move(t)));
}

// template <typename T>
// inline int enum_result_to_number_result(simdjson_result<T>&& enum_result) {
// T inner;
// auto error = std::move(enum_result).get(inner);
// if (error == error_code::SUCCESS) {

// }
// }

} // namespace

#define IMPL_CLASS(name, type) \
Expand Down Expand Up @@ -41,10 +50,9 @@ template <typename U, typename T> inline U object_to_pointer(T &&t) {
}

#define IMPL_AT_POINTER(self, type) \
SJ_OD_value_result *self##_at_pointer(self *self, const char *s, \
size_t len) { \
SJ_OD_value_result *self##_at_pointer(self *r, const char *s, size_t len) { \
auto result = \
reinterpret_cast<type *>(self)->at_pointer(std::string_view(s, len)); \
reinterpret_cast<type *>(r)->at_pointer(std::string_view(s, len)); \
return object_to_pointer<SJ_OD_value_result *>(std::move(result)); \
}

Expand All @@ -69,12 +77,15 @@ IMPL_CLASS(SJ_OD_object_iterator, ondemand::object_iterator)
IMPL_RESULT(SJ_OD_object_iterator, ondemand::object_iterator)
IMPL_CLASS(SJ_OD_field, ondemand::field)
IMPL_RESULT(SJ_OD_field, ondemand::field)
IMPL_CLASS(SJ_OD_number, ondemand::number)
IMPL_RESULT(SJ_OD_number, ondemand::number)

IMPL_PRIMITIVE_RESULT(uint64_t)
IMPL_PRIMITIVE_RESULT(int64_t)
IMPL_PRIMITIVE_RESULT(double)
IMPL_PRIMITIVE_RESULT(bool)
IMPL_PRIMITIVE_RESULT(size_t)
IMPL_PRIMITIVE_RESULT(int)

// SJ_padded_string *SJ_padded_string_new(const char *s, size_t len) {
// return object_to_pointer<SJ_padded_string *>(padded_string(s, len));
Expand Down Expand Up @@ -134,6 +145,9 @@ IMPL_GET(SJ_OD_value, ondemand::value, double, get_double)
IMPL_GET(SJ_OD_value, ondemand::value, SJ_OD_raw_json_string,
get_raw_json_string)
IMPL_GET(SJ_OD_value, ondemand::value, STD_string_view, get_wobbly_string)
IMPL_GET(SJ_OD_value, ondemand::value, bool, is_null)
IMPL_GET(SJ_OD_value, ondemand::value, int, type)
IMPL_GET(SJ_OD_value, ondemand::value, SJ_OD_number, get_number)
IMPL_AT_POINTER(SJ_OD_value, ondemand::value)

// ondemand::document
Expand All @@ -145,6 +159,9 @@ IMPL_GET(SJ_OD_document, ondemand::document, double, get_double)
IMPL_GET(SJ_OD_document, ondemand::document, SJ_OD_raw_json_string,
get_raw_json_string)
IMPL_GET(SJ_OD_document, ondemand::document, STD_string_view, get_wobbly_string)
IMPL_GET(SJ_OD_document, ondemand::document, bool, is_null)
IMPL_GET(SJ_OD_document, ondemand::document, int, type)
IMPL_GET(SJ_OD_document, ondemand::document, SJ_OD_number, get_number)
IMPL_AT_POINTER(SJ_OD_document, ondemand::document)

STD_string_view_result *SJ_OD_value_get_string(SJ_OD_value *self,
Expand Down Expand Up @@ -252,3 +269,18 @@ SJ_OD_value *SJ_OD_field_take_value(SJ_OD_field *self) {
auto value = std::move(*field).value();
return object_to_pointer<SJ_OD_value *>(std::move(value));
}

// ondemand::number
#define IMPL_GET_PRIMITIVE(self, real_name, value, method) \
value self##_##method(self *r) { \
return reinterpret_cast<real_name *>(r)->method(); \
}

IMPL_GET_PRIMITIVE(SJ_OD_number, ondemand::number, uint64_t, get_uint64)
IMPL_GET_PRIMITIVE(SJ_OD_number, ondemand::number, int64_t, get_int64)
IMPL_GET_PRIMITIVE(SJ_OD_number, ondemand::number, double, get_double)

int SJ_OD_number_get_number_type(SJ_OD_number *self) {
return static_cast<int>(
reinterpret_cast<ondemand::number *>(self)->get_number_type());
}
30 changes: 24 additions & 6 deletions simdjson-sys/src/simdjson_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
value##_result *self##_##method(self *r);

#define DEFINE_AT_POINTER(self) \
SJ_OD_value_result *self##_at_pointer(self *self, const char *s, size_t len);
SJ_OD_value_result *self##_at_pointer(self *r, const char *s, size_t len);

#define DEFINE_GET_PRIMITIVE(self, value, method) \
value self##_##method(self *r);

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -52,19 +55,22 @@ DEFINE_CLASS(SJ_OD_object_iterator)
DEFINE_RESULT(SJ_OD_object_iterator)
DEFINE_CLASS(SJ_OD_field)
DEFINE_RESULT(SJ_OD_field)
DEFINE_CLASS(SJ_OD_number)
DEFINE_RESULT(SJ_OD_number)

DEFINE_PRIMITIVE_RESULT(uint64_t)
DEFINE_PRIMITIVE_RESULT(int64_t)
DEFINE_PRIMITIVE_RESULT(double)
DEFINE_PRIMITIVE_RESULT(bool)
DEFINE_PRIMITIVE_RESULT(size_t)
DEFINE_PRIMITIVE_RESULT(int)

// padded_string
SJ_padded_string *SJ_padded_string_new(const char *s, size_t len);
SJ_padded_string_result *
SJ_padded_string_load(const char *path); // null terminated string.
size_t SJ_padded_string_length(const SJ_padded_string *ps);
const uint8_t *SJ_padded_string_u8data(const SJ_padded_string *ps);
// SJ_padded_string *SJ_padded_string_new(const char *s, size_t len);
// SJ_padded_string_result *
// SJ_padded_string_load(const char *path); // null terminated string.
// size_t SJ_padded_string_length(const SJ_padded_string *ps);
// const uint8_t *SJ_padded_string_u8data(const SJ_padded_string *ps);

// ondemand::parser
SJ_OD_parser *SJ_OD_parser_new(size_t max_capacity);
Expand All @@ -84,6 +90,9 @@ DEFINE_GET(SJ_OD_value, SJ_OD_array, get_array)
DEFINE_GET(SJ_OD_value, SJ_OD_object, get_object)
DEFINE_GET(SJ_OD_value, SJ_OD_raw_json_string, get_raw_json_string)
DEFINE_GET(SJ_OD_value, STD_string_view, get_wobbly_string)
DEFINE_GET(SJ_OD_value, bool, is_null)
DEFINE_GET(SJ_OD_value, int, type)
DEFINE_GET(SJ_OD_value, SJ_OD_number, get_number)
DEFINE_AT_POINTER(SJ_OD_value)

// ondemand::document
Expand All @@ -96,6 +105,9 @@ DEFINE_GET(SJ_OD_document, SJ_OD_array, get_array)
DEFINE_GET(SJ_OD_document, SJ_OD_object, get_object)
DEFINE_GET(SJ_OD_document, SJ_OD_raw_json_string, get_raw_json_string)
DEFINE_GET(SJ_OD_document, STD_string_view, get_wobbly_string)
DEFINE_GET(SJ_OD_document, bool, is_null)
DEFINE_GET(SJ_OD_document, int, type)
DEFINE_GET(SJ_OD_document, SJ_OD_number, get_number)
DEFINE_AT_POINTER(SJ_OD_document)

// get_string is special.
Expand Down Expand Up @@ -151,6 +163,12 @@ STD_string_view_result *SJ_OD_field_unescaped_key(SJ_OD_field *self,
SJ_OD_value *SJ_OD_field_value(SJ_OD_field *self);
SJ_OD_value *SJ_OD_field_take_value(SJ_OD_field *self);

// ondemand::number
DEFINE_GET_PRIMITIVE(SJ_OD_number, int, get_number_type)
DEFINE_GET_PRIMITIVE(SJ_OD_number, uint64_t, get_uint64)
DEFINE_GET_PRIMITIVE(SJ_OD_number, int64_t, get_int64)
DEFINE_GET_PRIMITIVE(SJ_OD_number, double, get_double)

#ifdef __cplusplus
}
#endif
30 changes: 29 additions & 1 deletion src/ondemand/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{marker::PhantomData, ptr::NonNull};

use simdjson_sys as ffi;

use super::{array::Array, object::Object, parser::Parser, value::Value};
use super::{array::Array, number::Number, object::Object, parser::Parser, value::Value, JsonType};
use crate::{
error::Result,
macros::{impl_drop, map_result},
Expand Down Expand Up @@ -116,6 +116,34 @@ impl<'p, 's> Document<'p, 's> {
)
.map(Value::new)
}

pub fn get_number<'a>(&mut self) -> Result<Number<'a>> {
map_result!(
ffi::SJ_OD_document_get_number(self.ptr.as_mut()),
ffi::SJ_OD_number_result_error,
ffi::SJ_OD_number_result_value_unsafe
)
.map(Number::new)
}

pub fn is_null(&mut self) -> Result<bool> {
map_result!(
primitive,
ffi::SJ_OD_document_is_null(self.ptr.as_mut()),
ffi::bool_result_error,
ffi::bool_result_value_unsafe
)
}

pub fn json_type(&mut self) -> Result<JsonType> {
let json_type = map_result!(
primitive,
ffi::SJ_OD_document_type(self.ptr.as_mut()),
ffi::int_result_error,
ffi::int_result_value_unsafe
)?;
Ok(JsonType::from(json_type))
}
}

impl_drop!(Document<'p, 's>, ffi::SJ_OD_document_free);
41 changes: 41 additions & 0 deletions src/ondemand/json_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#[derive(Debug, PartialEq)]
pub enum JsonType {
Array = 1,
Object,
Number,
String,
Boolean,
Null,
}

impl From<i32> for JsonType {
fn from(value: i32) -> Self {
match value {
1 => JsonType::Array,
2 => JsonType::Object,
3 => JsonType::Number,
4 => JsonType::String,
5 => JsonType::Boolean,
6 => JsonType::Null,
_ => panic!("Invalid JsonType value: {}", value),
}
}
}

#[derive(Debug, PartialEq)]
pub enum NumberType {
FloatingPointNumber = 1,
SignedInteger,
UnsignedInteger,
}

impl From<i32> for NumberType {
fn from(value: i32) -> Self {
match value {
1 => NumberType::FloatingPointNumber,
2 => NumberType::SignedInteger,
3 => NumberType::UnsignedInteger,
_ => panic!("Invalid NumberType value: {}", value),
}
}
}
3 changes: 3 additions & 0 deletions src/ondemand/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pub(crate) mod array;
pub(crate) mod array_iterator;
pub(crate) mod document;
pub(crate) mod field;
mod json_type;
mod number;
pub(crate) mod object;
pub(crate) mod object_iterator;
pub(crate) mod parser;
Expand All @@ -11,6 +13,7 @@ pub use array::Array;
pub use array_iterator::ArrayIterator;
pub use document::Document;
pub use field::Field;
pub use json_type::{JsonType, NumberType};
pub use object::Object;
pub use object_iterator::ObjectIterator;
pub use parser::Parser;
Expand Down
38 changes: 38 additions & 0 deletions src/ondemand/number.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::{marker::PhantomData, ptr::NonNull};

use simdjson_sys as ffi;

use super::{Document, NumberType};
use crate::macros::impl_drop;

pub struct Number<'a> {
ptr: NonNull<ffi::SJ_OD_number>,
_doc: PhantomData<&'a mut Document<'a, 'a>>,
}

impl<'a> Number<'a> {
pub fn new(ptr: NonNull<ffi::SJ_OD_number>) -> Self {
Self {
ptr,
_doc: PhantomData,
}
}

pub fn get_uint64(&mut self) -> u64 {
unsafe { ffi::SJ_OD_number_get_uint64(self.ptr.as_mut()) }
}

pub fn get_int64(&mut self) -> i64 {
unsafe { ffi::SJ_OD_number_get_int64(self.ptr.as_mut()) }
}

pub fn get_double(&mut self) -> f64 {
unsafe { ffi::SJ_OD_number_get_double(self.ptr.as_mut()) }
}

pub fn get_number_type(&mut self) -> NumberType {
unsafe { ffi::SJ_OD_number_get_number_type(self.ptr.as_mut()) }.into()
}
}

impl_drop!(Number<'a>, ffi::SJ_OD_number_free);
Loading

0 comments on commit 4ef4b84

Please sign in to comment.