Skip to content

Commit 49df51c

Browse files
committed
handle correctly in rust too
1 parent 9ae7924 commit 49df51c

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ prettyplease = { version = "0.2.4", optional = true }
4747
schemars = { version = "0.8.0", optional = true }
4848
syn = { version = "2.0.11", optional = true }
4949
typify = { version = "0.0.16", optional = true }
50+
url = "2.5.4"
5051

5152
[build-dependencies]
5253
prettyplease = { version = "0.2.4", optional = true }

rust/lib.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use jsonschema::JSONSchema;
1+
use jsonschema::{JSONSchema, SchemaResolver, SchemaResolverError};
22
use serde::{Deserialize, Serialize};
33
use thiserror::Error;
4-
4+
use serde_json::Value;
5+
use std::{sync::Arc};
6+
use url::Url;
57
// This file is supposed to be auto-generated via rust/build.rs
68
pub mod schema_types {
79
include!(concat!(env!("OUT_DIR"), "/schema_types.rs"));
@@ -148,6 +150,32 @@ fn get_topic_schema(topic: &str, version: Option<u16>) -> Result<TopicSchema, Sc
148150
Ok(schema_metadata)
149151
}
150152

153+
struct FileSchemaResolver { }
154+
155+
impl FileSchemaResolver {
156+
fn new() -> Self {
157+
Self { }
158+
}
159+
}
160+
161+
impl SchemaResolver for FileSchemaResolver {
162+
fn resolve(&self, _root_schema: &Value, url: &Url, _original_reference: &str) -> Result<Arc<Value>, SchemaResolverError> {
163+
if url.scheme() == "file" {
164+
let url_str = url.as_str();
165+
let relative_path = &url_str[7..url_str.len() - 1];
166+
let schema = find_entry(SCHEMAS, relative_path).ok_or(SchemaError::InvalidSchema)?;
167+
let schema_json = serde_json::from_str(schema).map_err(|_| SchemaError::InvalidSchema)?;
168+
return Ok(Arc::new(schema_json));
169+
170+
}
171+
172+
Err(SchemaResolverError::new(Box::new(std::io::Error::new(
173+
std::io::ErrorKind::NotFound,
174+
format!("Unsupported URL scheme: {}", url.scheme()),
175+
))))
176+
}
177+
}
178+
151179
/// Returns the schema for a topic. If `version` is passed, return the schema for
152180
/// the specified version, otherwise the latest version is returned.
153181
///
@@ -163,7 +191,8 @@ pub fn get_schema(topic: &str, version: Option<u16>) -> Result<Schema, SchemaErr
163191
find_entry(SCHEMAS, &schema_metadata.resource).ok_or(SchemaError::InvalidSchema)?;
164192

165193
let s = serde_json::from_str(schema).map_err(|_| SchemaError::InvalidSchema)?;
166-
let compiled_json_schema = JSONSchema::compile(&s).map_err(|_| SchemaError::InvalidSchema)?;
194+
let resolver = FileSchemaResolver::new();
195+
let compiled_json_schema = JSONSchema::options().with_resolver(resolver).compile(&s).map_err(|_| SchemaError::InvalidSchema)?;
167196

168197
// FIXME(swatinem): This assumes that there is only a single `examples` entry in the definition.
169198
// If we would want to support multiple, we would have to either merge those in code generation,
@@ -209,11 +238,11 @@ mod tests {
209238
// Did not error
210239
get_schema("snuba-queries", Some(1)).unwrap();
211240
get_schema("transactions", Some(1)).unwrap();
241+
get_schema("snuba-uptime-results", Some(1)).unwrap();
212242
}
213243

214-
#[test]
215-
fn test_validate() {
216-
let schema = get_schema("snuba-queries", None).unwrap();
244+
fn validate_schema(schema_name: &str) {
245+
let schema = get_schema(schema_name, None).unwrap();
217246

218247
let examples = schema.examples();
219248
assert!(!examples.is_empty());
@@ -226,4 +255,11 @@ mod tests {
226255
Err(SchemaError::InvalidMessage)
227256
));
228257
}
258+
259+
#[test]
260+
fn test_validate() {
261+
validate_schema("snuba-queries");
262+
validate_schema("uptime-results");
263+
validate_schema("snuba-uptime-results");
264+
}
229265
}

0 commit comments

Comments
 (0)