diff --git a/crates/jsonschema-referencing/src/list.rs b/crates/jsonschema-referencing/src/list.rs index 5e428c41..279135f4 100644 --- a/crates/jsonschema-referencing/src/list.rs +++ b/crates/jsonschema-referencing/src/list.rs @@ -34,7 +34,7 @@ impl List { self.head.is_none() } #[must_use] - pub fn push_front(&self, value: T) -> Self { + pub fn push_front(&self, value: Arc) -> Self { List { head: Some(Arc::new(Node { value, @@ -52,7 +52,7 @@ impl List { #[derive(Debug)] pub(crate) struct Node { - value: T, + value: Arc, next: Option>>, } @@ -68,7 +68,7 @@ impl<'a, T> Iterator for Iter<'a, T> { self.current.map(|current| { let value = ¤t.value; self.current = current.next.as_ref(); - value + &**value }) } } diff --git a/crates/jsonschema-referencing/src/registry.rs b/crates/jsonschema-referencing/src/registry.rs index e5778186..ba6b7bb5 100644 --- a/crates/jsonschema-referencing/src/registry.rs +++ b/crates/jsonschema-referencing/src/registry.rs @@ -223,12 +223,12 @@ impl Registry { /// Create a new [`Resolver`] for this registry with a known valid base URI. #[must_use] pub fn resolver(&self, base_uri: Uri) -> Resolver { - Resolver::new(self, base_uri) + Resolver::new(self, Arc::new(base_uri)) } #[must_use] pub fn resolver_from_raw_parts( &self, - base_uri: Uri, + base_uri: Arc>, scopes: List>, ) -> Resolver { Resolver::from_parts(self, base_uri, scopes) diff --git a/crates/jsonschema-referencing/src/resolver.rs b/crates/jsonschema-referencing/src/resolver.rs index 29c95fb9..8a752754 100644 --- a/crates/jsonschema-referencing/src/resolver.rs +++ b/crates/jsonschema-referencing/src/resolver.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::sync::Arc; use fluent_uri::Uri; use serde_json::Value; @@ -11,7 +12,7 @@ use crate::{list::List, uri, Draft, Error, Registry, ResourceRef}; #[derive(Clone)] pub struct Resolver<'r> { pub(crate) registry: &'r Registry, - base_uri: Uri, + base_uri: Arc>, scopes: List>, } @@ -45,7 +46,7 @@ impl<'r> fmt::Debug for Resolver<'r> { impl<'r> Resolver<'r> { /// Create a new `Resolver` with the given registry and base URI. - pub(crate) fn new(registry: &'r Registry, base_uri: Uri) -> Self { + pub(crate) fn new(registry: &'r Registry, base_uri: Arc>) -> Self { Self { registry, base_uri, @@ -54,7 +55,7 @@ impl<'r> Resolver<'r> { } pub(crate) fn from_parts( registry: &'r Registry, - base_uri: Uri, + base_uri: Arc>, scopes: List>, ) -> Self { Self { @@ -64,8 +65,8 @@ impl<'r> Resolver<'r> { } } #[must_use] - pub fn base_uri(&self) -> Uri<&str> { - self.base_uri.borrow() + pub fn base_uri(&self) -> Arc> { + self.base_uri.clone() } /// Resolve a reference to the resource it points to. /// @@ -81,7 +82,7 @@ impl<'r> Resolver<'r> { } else { (reference, "") }; - let uri = uri::resolve_against(&self.base_uri.borrow(), uri)?; + let uri = Arc::new(uri::resolve_against(&self.base_uri.borrow(), uri)?); (uri, fragment) }; @@ -155,7 +156,7 @@ impl<'r> Resolver<'r> { /// Returns an error if the resource id cannot be resolved against the base URI of this resolver. pub fn in_subresource(&self, subresource: ResourceRef) -> Result { if let Some(id) = subresource.id() { - let base_uri = uri::resolve_against(&self.base_uri.borrow(), id)?; + let base_uri = Arc::new(uri::resolve_against(&self.base_uri.borrow(), id)?); Ok(Resolver { registry: self.registry, base_uri, @@ -169,7 +170,7 @@ impl<'r> Resolver<'r> { pub fn dynamic_scope(&self) -> List> { self.scopes.clone() } - fn evolve(&self, base_uri: Uri) -> Resolver<'r> { + fn evolve(&self, base_uri: Arc>) -> Resolver<'r> { if !self.base_uri.as_str().is_empty() && (self.scopes.is_empty() || base_uri != self.base_uri) { diff --git a/crates/jsonschema/src/compiler.rs b/crates/jsonschema/src/compiler.rs index 59125534..4ccefb88 100644 --- a/crates/jsonschema/src/compiler.rs +++ b/crates/jsonschema/src/compiler.rs @@ -26,6 +26,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc}; const DEFAULT_SCHEME: &str = "json-schema"; pub(crate) const DEFAULT_ROOT_URL: &str = "json-schema:///"; type BaseUri = Uri; +type ResolverComponents = (Arc, List, Resource); /// Container for information required to build a tree. /// @@ -123,7 +124,7 @@ impl<'a> Context<'a> { if base_uri.scheme().as_str() == DEFAULT_SCHEME { None } else { - Some(base_uri.to_owned()) + Some((*base_uri).clone()) } } fn is_known_keyword(&self, keyword: &str) -> bool { @@ -186,11 +187,11 @@ impl<'a> Context<'a> { &self, reference: &str, ) -> Result { - let uri = uri::resolve_against(&self.resolver.base_uri(), reference)?; + let uri = uri::resolve_against(&self.resolver.base_uri().borrow(), reference)?; Ok(self.seen.borrow().contains(&uri)) } pub(crate) fn mark_seen(&self, reference: &str) -> Result<(), referencing::Error> { - let uri = uri::resolve_against(&self.resolver.base_uri(), reference)?; + let uri = uri::resolve_against(&self.resolver.base_uri().borrow(), reference)?; self.seen.borrow_mut().insert(uri); Ok(()) } @@ -204,7 +205,7 @@ impl<'a> Context<'a> { &self, reference: &str, is_recursive: bool, - ) -> Result, Resource)>, ValidationError<'static>> { + ) -> Result, ValidationError<'static>> { let resolved = if reference == "#" { // Known & simple recursive reference // It may also use some additional logic from the `$recursiveAnchor` keyword @@ -223,7 +224,7 @@ impl<'a> Context<'a> { let mut base_uri = resolved.resolver().base_uri().to_owned(); let scopes = resolved.resolver().dynamic_scope(); if let Some(id) = resource.id() { - base_uri = uri::resolve_against(&base_uri.borrow(), id)?; + base_uri = Arc::new(uri::resolve_against(&base_uri.borrow(), id)?); }; Ok(Some((base_uri, scopes, resource))) } diff --git a/crates/jsonschema/src/keywords/ref_.rs b/crates/jsonschema/src/keywords/ref_.rs index f66c7c0c..9e661a23 100644 --- a/crates/jsonschema/src/keywords/ref_.rs +++ b/crates/jsonschema/src/keywords/ref_.rs @@ -62,7 +62,7 @@ pub(crate) struct LazyRefValidator { config: Arc, registry: Arc, scopes: List>, - base_uri: Uri, + base_uri: Arc>, draft: Draft, inner: OnceCell, } @@ -73,9 +73,9 @@ impl LazyRefValidator { let scopes = ctx.scopes(); let resolved = ctx.lookup_recursive_reference()?; let resource = ctx.draft().create_resource(resolved.contents().clone()); - let mut base_uri = resolved.resolver().base_uri().to_owned(); + let mut base_uri = resolved.resolver().base_uri(); if let Some(id) = resource.id() { - base_uri = uri::resolve_against(&base_uri.borrow(), id)?; + base_uri = Arc::new(uri::resolve_against(&base_uri.borrow(), id)?); }; Ok(Box::new(LazyRefValidator { resource,