rusty_json_schema 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Cargo.toml +13 -0
- data/README.md +53 -0
- data/lib/ext/json_schema.d +1 -0
- data/lib/ext/json_schema.dll +0 -0
- data/lib/ext/json_schema.dll.exp +0 -0
- data/lib/ext/json_schema.dll.lib +0 -0
- data/lib/ext/json_schema.pdb +0 -0
- data/lib/ext/libjson_schema.d +1 -0
- data/lib/ext/libjson_schema.dylib +0 -0
- data/lib/ext/libjson_schema.so +0 -0
- data/lib/rusty_json_schema.rb +64 -0
- data/lib/rusty_json_schema/version.rb +7 -0
- data/rusty_json_schema.gemspec +32 -0
- data/src/lib.rs +118 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e89b25e8e45ded120281d3b9b6af8a85bf5b8d0cb4f86b2f339485d629cf4dfd
|
4
|
+
data.tar.gz: 1c6859709cd625af4184235dc09b1dfdaf05b8d0aca6fe8998c13c8bc11c1c4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 27da18c9402b2f91c92a75f97f31ad0eb9761aa322634e79ac4dd4b735bdb1d9e138821991a41c03648be01cc8ec1f15a13868cf96f65421b1d6a00f2bac226f
|
7
|
+
data.tar.gz: c09eaf66fce3eb9daa15c9ab78a23fa82276a7aeb2176ca23579936ff6bf798e7990731937662fc63c0d42ce7a6c59c45efbc4a5509722c84b3be16d1b3a481b
|
data/Cargo.toml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
[package]
|
2
|
+
name = "json_schema"
|
3
|
+
version = "0.1.0"
|
4
|
+
authors = ["Leszek Zalewski <leszekzalewski@fastmail.fm>"]
|
5
|
+
edition = "2018"
|
6
|
+
|
7
|
+
[lib]
|
8
|
+
name = "json_schema"
|
9
|
+
crate-type = ["cdylib"]
|
10
|
+
|
11
|
+
[dependencies]
|
12
|
+
jsonschema = "0.4.3"
|
13
|
+
serde_json = "1.0"
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# RustyJSONSchema
|
2
|
+
|
3
|
+
FFI wrapper around [`jsonschema`](https://github.com/Stranger6667/jsonschema-rs) rust library. Props go to original project.
|
4
|
+
|
5
|
+
Currently during heavy development.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem "rusty_json_schema"
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install rusty_json_schema
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Initialize schema validator
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
validator = RustyJSONSchema.build(json_schema)
|
29
|
+
```
|
30
|
+
|
31
|
+
Validate events like
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
validator.valid?(event_json)
|
35
|
+
```
|
36
|
+
|
37
|
+
## Development
|
38
|
+
|
39
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
40
|
+
|
41
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
42
|
+
|
43
|
+
## Contributing
|
44
|
+
|
45
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/driv3r/rusty_json_schema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/driv3r/rusty_json_schema/blob/master/CODE_OF_CONDUCT.md).
|
46
|
+
|
47
|
+
## License
|
48
|
+
|
49
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
50
|
+
|
51
|
+
## Code of Conduct
|
52
|
+
|
53
|
+
Everyone interacting in the RustyJSONSchema project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/driv3r/rusty_json_schema/blob/master/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1 @@
|
|
1
|
+
D:\a\rusty_json_schema\rusty_json_schema\target\x86_64-pc-windows-msvc\release\json_schema.dll: D:\a\rusty_json_schema\rusty_json_schema\src\lib.rs
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
/home/runner/work/rusty_json_schema/rusty_json_schema/target/x86_64-unknown-linux-gnu/release/libjson_schema.so: /home/runner/work/rusty_json_schema/rusty_json_schema/src/lib.rs
|
Binary file
|
Binary file
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ffi"
|
4
|
+
|
5
|
+
require_relative "rusty_json_schema/version"
|
6
|
+
|
7
|
+
# JSON Schema validation
|
8
|
+
#
|
9
|
+
# ## Example
|
10
|
+
#
|
11
|
+
# validator = RustyJSONSchema.build(schema) # where schema is a json string of the schema
|
12
|
+
# validator.valid?(event) # where event is a json string of schema
|
13
|
+
# # => true/false
|
14
|
+
#
|
15
|
+
module RustyJSONSchema
|
16
|
+
|
17
|
+
def self.build(schema)
|
18
|
+
RustyJSONSchema::Validator::Binding.new(schema)
|
19
|
+
end
|
20
|
+
|
21
|
+
class Error < StandardError; end
|
22
|
+
|
23
|
+
# Handles release of the pointer automatically
|
24
|
+
# with Ruby GC. This way we can intialize validator
|
25
|
+
# in Rust, and hold a reference in Ruby.
|
26
|
+
#
|
27
|
+
class Validator < FFI::AutoPointer
|
28
|
+
|
29
|
+
# Custom GC flow for our validator, freeing
|
30
|
+
# the object within Rust
|
31
|
+
#
|
32
|
+
def self.release(pointer)
|
33
|
+
Binding.free(pointer)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Simple validation without actual error messages
|
37
|
+
#
|
38
|
+
def valid?(event)
|
39
|
+
Binding.is_valid(self, event)
|
40
|
+
end
|
41
|
+
|
42
|
+
# FFI container for our library.
|
43
|
+
#
|
44
|
+
module Binding
|
45
|
+
|
46
|
+
extend FFI::Library
|
47
|
+
|
48
|
+
lib_name =
|
49
|
+
case ::FFI::Platform::LIBSUFFIX
|
50
|
+
when "so", "dylib" then "libjson_schema"
|
51
|
+
when "dll" then "json_schema"
|
52
|
+
end
|
53
|
+
|
54
|
+
ffi_lib File.expand_path("ext/#{lib_name}.#{::FFI::Platform::LIBSUFFIX}", __dir__)
|
55
|
+
|
56
|
+
attach_function :new, :validator_new, [:string], Validator
|
57
|
+
attach_function :free, :validator_free, [Validator], :void
|
58
|
+
attach_function :is_valid, :validator_is_valid, [Validator, :string], :bool
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/rusty_json_schema/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "rusty_json_schema"
|
7
|
+
spec.version = RustyJSONSchema::VERSION
|
8
|
+
spec.authors = ["Leszek Zalewski"]
|
9
|
+
spec.email = ["leszekzalewski@fastmail.fm"]
|
10
|
+
spec.license = "MIT"
|
11
|
+
spec.homepage = "https://github.com/driv3r/rusty_json_schema"
|
12
|
+
spec.summary = "FFI wrapper around jsonschema-rs Rust library."
|
13
|
+
spec.description = <<-STR
|
14
|
+
FFI wrapper around https://github.com/Stranger6667/jsonschema-rs Rust library.
|
15
|
+
|
16
|
+
Currently during heavy development.
|
17
|
+
STR
|
18
|
+
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
20
|
+
|
21
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
22
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
24
|
+
spec.metadata["changelog_uri"] = "https://github.com/driv3r/rusty_json_schema/blob/main/CHANGELOG.md"
|
25
|
+
|
26
|
+
spec.files = Dir["lib/**/*", "src/**/*.rs", "rusty_json_schema.gemspec", "Cargo.toml", "LICENSE", "README.md"]
|
27
|
+
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
# Uncomment to register a new dependency of your gem
|
31
|
+
spec.add_dependency "ffi", "~> 1.14"
|
32
|
+
end
|
data/src/lib.rs
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
use jsonschema::JSONSchema;
|
2
|
+
use serde_json::Value;
|
3
|
+
|
4
|
+
use std::ffi::CStr;
|
5
|
+
use std::os::raw::c_char;
|
6
|
+
|
7
|
+
/*
|
8
|
+
* Our wrapper struct for schema and schema value,
|
9
|
+
* we need to hold onto value in order to not have
|
10
|
+
* it freed up, as JSONSchema uses it as reference.
|
11
|
+
*/
|
12
|
+
pub struct Validator {
|
13
|
+
schema: &'static JSONSchema<'static>,
|
14
|
+
schema_value: &'static Value,
|
15
|
+
}
|
16
|
+
|
17
|
+
impl Validator {
|
18
|
+
/*
|
19
|
+
* With Box::leak we avoid freeing up of schema
|
20
|
+
* and schema value, we free them up separately
|
21
|
+
* in the Drop implementation
|
22
|
+
*/
|
23
|
+
fn new(schema: Value) -> Validator {
|
24
|
+
let boxed_schema: &'static Value = Box::leak(Box::new(schema));
|
25
|
+
let boxed_compile: &'static JSONSchema<'static> = Box::leak(Box::new(JSONSchema::compile(boxed_schema).unwrap()));
|
26
|
+
|
27
|
+
Validator {
|
28
|
+
schema: boxed_compile,
|
29
|
+
schema_value: boxed_schema,
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
fn is_valid(&self, event: &Value) -> bool {
|
34
|
+
self.schema.is_valid(event)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
impl Drop for Validator {
|
39
|
+
/*
|
40
|
+
* Free up schema with value by "materializing" them,
|
41
|
+
* otherwise they will leak memory.
|
42
|
+
*/
|
43
|
+
fn drop(&mut self) {
|
44
|
+
unsafe {
|
45
|
+
Box::from_raw(self.schema as *const _ as *mut JSONSchema);
|
46
|
+
Box::from_raw(self.schema_value as *const _ as *mut Value);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
fn to_string(ptr: *const c_char) -> &'static CStr {
|
52
|
+
unsafe {
|
53
|
+
assert!(!ptr.is_null());
|
54
|
+
CStr::from_ptr(ptr)
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
#[no_mangle]
|
59
|
+
pub extern "C" fn validator_new(c_schema: *const c_char) -> *mut Validator {
|
60
|
+
let raw_schema = to_string(c_schema);
|
61
|
+
let schema = serde_json::from_slice(raw_schema.to_bytes()).unwrap();
|
62
|
+
let validator = Validator::new(schema);
|
63
|
+
|
64
|
+
Box::into_raw(Box::new(validator))
|
65
|
+
}
|
66
|
+
|
67
|
+
#[no_mangle]
|
68
|
+
pub extern "C" fn validator_free(ptr: *mut Validator) {
|
69
|
+
if ptr.is_null() {
|
70
|
+
return;
|
71
|
+
}
|
72
|
+
|
73
|
+
unsafe {
|
74
|
+
Box::from_raw(ptr);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
#[no_mangle]
|
79
|
+
pub extern "C" fn validator_is_valid(ptr: *const Validator, event: *const c_char) -> bool {
|
80
|
+
let validator = unsafe {
|
81
|
+
assert!(!ptr.is_null());
|
82
|
+
&*ptr
|
83
|
+
};
|
84
|
+
|
85
|
+
let raw_event = to_string(event);
|
86
|
+
let event: Value = serde_json::from_slice(raw_event.to_bytes()).unwrap();
|
87
|
+
|
88
|
+
validator.is_valid(&event)
|
89
|
+
}
|
90
|
+
|
91
|
+
#[cfg(test)]
|
92
|
+
mod tests {
|
93
|
+
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
94
|
+
use super::*;
|
95
|
+
use std::ffi::CString;
|
96
|
+
use std::{thread, time};
|
97
|
+
|
98
|
+
/*
|
99
|
+
* Simple sanity check if everything works together
|
100
|
+
*/
|
101
|
+
#[test]
|
102
|
+
fn test_valid_event() {
|
103
|
+
let schema = CString::new("{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"array\",\"items\":[{\"type\":\"number\",\"exclusiveMaximum\":10}]}").unwrap();
|
104
|
+
let valid_event = CString::new("[9]").unwrap();
|
105
|
+
let invalid_event = CString::new("[22]").unwrap();
|
106
|
+
|
107
|
+
let c_schema_ptr: *const c_char = schema.as_ptr();
|
108
|
+
let c_valid_event_ptr: *const c_char = valid_event.as_ptr();
|
109
|
+
let c_invalid_event_ptr: *const c_char = invalid_event.as_ptr();
|
110
|
+
|
111
|
+
let validator = validator_new(c_schema_ptr);
|
112
|
+
|
113
|
+
assert!(validator_is_valid(validator, c_valid_event_ptr));
|
114
|
+
assert!(!validator_is_valid(validator, c_invalid_event_ptr));
|
115
|
+
|
116
|
+
validator_free(validator);
|
117
|
+
}
|
118
|
+
}
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rusty_json_schema
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leszek Zalewski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
description: |2
|
28
|
+
FFI wrapper around https://github.com/Stranger6667/jsonschema-rs Rust library.
|
29
|
+
|
30
|
+
Currently during heavy development.
|
31
|
+
email:
|
32
|
+
- leszekzalewski@fastmail.fm
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- Cargo.toml
|
38
|
+
- README.md
|
39
|
+
- lib/ext/json_schema.d
|
40
|
+
- lib/ext/json_schema.dll
|
41
|
+
- lib/ext/json_schema.dll.exp
|
42
|
+
- lib/ext/json_schema.dll.lib
|
43
|
+
- lib/ext/json_schema.pdb
|
44
|
+
- lib/ext/libjson_schema.d
|
45
|
+
- lib/ext/libjson_schema.dylib
|
46
|
+
- lib/ext/libjson_schema.so
|
47
|
+
- lib/rusty_json_schema.rb
|
48
|
+
- lib/rusty_json_schema/version.rb
|
49
|
+
- rusty_json_schema.gemspec
|
50
|
+
- src/lib.rs
|
51
|
+
homepage: https://github.com/driv3r/rusty_json_schema
|
52
|
+
licenses:
|
53
|
+
- MIT
|
54
|
+
metadata:
|
55
|
+
allowed_push_host: https://rubygems.org
|
56
|
+
homepage_uri: https://github.com/driv3r/rusty_json_schema
|
57
|
+
source_code_uri: https://github.com/driv3r/rusty_json_schema
|
58
|
+
changelog_uri: https://github.com/driv3r/rusty_json_schema/blob/main/CHANGELOG.md
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.5.0
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.7.3
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: FFI wrapper around jsonschema-rs Rust library.
|
79
|
+
test_files: []
|