pub struct SchemaDiscoveryService { /* private fields */ }Expand description
Intelligent schema discovery service
Infers JSON Schemas from content using local heuristics and an optional AI provider. Maintains a schema cache for URL patterns and supports user corrections.
Implementations§
Source§impl SchemaDiscoveryService
impl SchemaDiscoveryService
Sourcepub fn new(
config: SchemaDiscoveryConfig,
ai_provider: Option<Arc<dyn AIProvider>>,
) -> Self
pub fn new( config: SchemaDiscoveryConfig, ai_provider: Option<Arc<dyn AIProvider>>, ) -> Self
Create a new schema discovery service
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
let service = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);Sourcepub fn with_graphql_service(self, service: Arc<dyn ScrapingService>) -> Self
pub fn with_graphql_service(self, service: Arc<dyn ScrapingService>) -> Self
Attach a GraphQL scraping service used by infer_from_graphql.
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
use stygian_graph::adapters::graphql::GraphQlService;
use std::sync::Arc;
let gql = Arc::new(GraphQlService::new(Default::default(), None));
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None)
.with_graphql_service(gql);Sourcepub fn infer_from_example(&self, example: &Value) -> Value
pub fn infer_from_example(&self, example: &Value) -> Value
Infer a JSON Schema by type-inspecting a JSON example value.
Supports objects, arrays, strings, numbers, booleans, and null.
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
use serde_json::json;
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);
let example = json!({"name": "Alice", "score": 9.5, "active": true});
let schema = svc.infer_from_example(&example);
assert_eq!(schema["type"].as_str().unwrap(), "object");
assert_eq!(schema["properties"]["name"]["type"].as_str().unwrap(), "string");
assert_eq!(schema["properties"]["score"]["type"].as_str().unwrap(), "number");Sourcepub async fn infer_from_html(
&self,
html: &str,
url_pattern: Option<&str>,
) -> Result<DiscoveredSchema>
pub async fn infer_from_html( &self, html: &str, url_pattern: Option<&str>, ) -> Result<DiscoveredSchema>
Infer a schema from HTML content using an AI provider.
Returns an error if no AI provider is configured.
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
let service = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);
// Without an AI provider, this returns Err
let result = service.infer_from_html("<html>...</html>", None).await;
assert!(result.is_err());Sourcepub fn add_correction(&self, field_name: String, schema_fragment: Value)
pub fn add_correction(&self, field_name: String, schema_fragment: Value)
Register a user correction for a specific field type
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
use serde_json::json;
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);
// Always use "integer" for "id" fields regardless of inferred type
svc.add_correction("id".to_string(), json!({"type": "integer"}));Sourcepub fn cache_schema(
&self,
url_pattern: String,
schema: Value,
source: SchemaSource,
confidence: f32,
)
pub fn cache_schema( &self, url_pattern: String, schema: Value, source: SchemaSource, confidence: f32, )
Cache a schema for a URL pattern (useful for preloading known schemas)
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig, SchemaSource};
use serde_json::json;
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);
svc.cache_schema(
"example.com/products".to_string(),
json!({"type": "object"}),
SchemaSource::UserCorrection,
1.0,
);Sourcepub fn detect_evolution(
&self,
old_schema: &Value,
new_schema: &Value,
) -> SchemaDiff
pub fn detect_evolution( &self, old_schema: &Value, new_schema: &Value, ) -> SchemaDiff
Detect schema evolution between a known schema and a newly inferred one.
Returns a diff describing added/removed/changed fields.
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
use serde_json::json;
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None);
let old = json!({
"type": "object",
"properties": {"name": {"type": "string"}, "price": {"type": "number"}}
});
let new = json!({
"type": "object",
"properties": {"name": {"type": "string"}, "discount": {"type": "number"}}
});
let diff = svc.detect_evolution(&old, &new);
assert!(diff.added_fields.contains(&"discount".to_string()));
assert!(diff.removed_fields.contains(&"price".to_string()));Sourcepub async fn infer_from_graphql(
&self,
endpoint: &str,
auth: Option<GraphQlAuth>,
) -> Result<DiscoveredSchema>
pub async fn infer_from_graphql( &self, endpoint: &str, auth: Option<GraphQlAuth>, ) -> Result<DiscoveredSchema>
Discover a JSON Schema by introspecting a live GraphQL endpoint.
Fires the standard __schema introspection query, converts the returned
SDL types to a JSON Schema representation, and caches the result by
endpoint URL.
§Errors
Returns Err if no GraphQL service is configured, if the endpoint is
unreachable, if the response contains GraphQL errors, or if the
introspection response cannot be parsed.
§Example
use stygian_graph::application::schema_discovery::{SchemaDiscoveryService, SchemaDiscoveryConfig};
use stygian_graph::adapters::graphql::GraphQlService;
use std::sync::Arc;
let gql = Arc::new(GraphQlService::new(Default::default(), None));
let svc = SchemaDiscoveryService::new(SchemaDiscoveryConfig::default(), None)
.with_graphql_service(gql);
let schema = svc.infer_from_graphql("https://api.example.com/graphql", None).await;Sourcepub fn is_valid_schema(schema: &Value) -> bool
pub fn is_valid_schema(schema: &Value) -> bool
Validate that a value is a structurally valid JSON Schema object.
Checks for the presence of a type or properties field.
§Example
use stygian_graph::application::schema_discovery::SchemaDiscoveryService;
use serde_json::json;
assert!(SchemaDiscoveryService::is_valid_schema(&json!({"type": "object"})));
assert!(!SchemaDiscoveryService::is_valid_schema(&json!("not a schema")));Auto Trait Implementations§
impl Freeze for SchemaDiscoveryService
impl !RefUnwindSafe for SchemaDiscoveryService
impl Send for SchemaDiscoveryService
impl Sync for SchemaDiscoveryService
impl Unpin for SchemaDiscoveryService
impl !UnwindSafe for SchemaDiscoveryService
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute] value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi [Quirk] value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);