-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Schema Value to be Owned #145
Comments
…the limitation mentioned here Stranger6667/jsonschema#145
@kayyagari I know that this doesn't address making the schema value owned, but your example is probably a good use case for Box::leak. In this case leaking the memory doesn't matter since you want the value to exist for the duration of the program. let schema: Value = serde_json::from_reader(schema_file).unwrap();
let schema_boxed: &'static Value = Box::leak(Box::new(schema));
let validator = JSONSchema::compile(&schema_boxed).unwrap(); |
I have encountered same issue, tried to workaround it by lying to the compiler about the lifetime of the input json like this: /// IMPORTANT: this struct must not be moved
/// this is a self referential struct: JSONSchema holds a reference to doc
pub struct Schema<'a> {
// step1: we need to move doc here, so that it's address is fixed
pub doc: Value,
// step2: we create schema with self.doc, and move it here
pub compiled: Option<JSONSchema<'a>>,
}
impl<'a> Schema<'a> {
fn compile(&mut self, options: &CompilationOptions) {
// IMPORTANT: here we lie about doc's lifetime
let doc: &'static Value = unsafe { std::mem::transmute(&self.doc) };
let compiled = options.compile(doc).unwrap();
self.compiled = Some(compiled);
}
} What I was doing is to load many schemas and put them into a hashmap: {
schemas: HashMap<String, Box<Schema<'a>>>,
}
// at some point:
let mut schema = Box::new(Schema {
compiled: None,
doc: doc.clone(),
});
schema.compile(&self.options);
self.schemas.insert(name.to_string(), schema); I think one possible way to improve this is to let the compile method 'consume' the json Value so that the resulted JSONSchema contains the input data instead of holding a reference, this could make this use-case much simpler. |
I also hit this issue and banged my head against the wall on it. I'm learning Rust and thought I was doing something stupid. |
A common use case is to compile a schema once and reuse it for validation multiple times. |
I would love this to be a feature. It's a mess when trying to create a service that validates multiple object types with caching built in. |
Also running into this exact issue building exactly this:
Is the official answer to do a |
This seems like it would also be useful for |
Folks, I completely agree with the mentioned points and would like to have it changed this way. Maybe I overestimated the impact (compilation usually happens much less often than validation), and it will be alright to clone the input schema into Also, I am sorry that this design flaw got you blocked from using the library in the mentioned use cases for such a long time. At the moment, I don't have much bandwidth to work on this, but I will happily review a PR that brings this change. |
I can take this on. My main question is do we care about API breakage? |
Awesome! I think that with this kind of change, the breakage is inevitable and is nicely motivated by the comments above. However, it would be nice to reduce the breakage surface if we can, but it should not block us from this kind of usability improvement. |
Released in |
In the current form it is impossible to retain a non-static reference to
JSONSchema
until the end of the program's execution. The below block demonstrates the problem.The above code results in the below compiler error:
One(or the only?) way to get this fixed is to let
JSONSchema
own theValue
containing schema.The text was updated successfully, but these errors were encountered: