mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-12 03:12:11 +02:00
Initial public Omnigraph repository
This commit is contained in:
commit
338289656a
110 changed files with 60747 additions and 0 deletions
111
crates/omnigraph-compiler/src/schema/ast.rs
Normal file
111
crates/omnigraph-compiler/src/schema/ast.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
use crate::types::PropType;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct SchemaFile {
|
||||
pub declarations: Vec<SchemaDecl>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum SchemaDecl {
|
||||
Interface(InterfaceDecl),
|
||||
Node(NodeDecl),
|
||||
Edge(EdgeDecl),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct InterfaceDecl {
|
||||
pub name: String,
|
||||
pub properties: Vec<PropDecl>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct NodeDecl {
|
||||
pub name: String,
|
||||
pub annotations: Vec<Annotation>,
|
||||
pub implements: Vec<String>,
|
||||
pub properties: Vec<PropDecl>,
|
||||
pub constraints: Vec<Constraint>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct EdgeDecl {
|
||||
pub name: String,
|
||||
pub from_type: String,
|
||||
pub to_type: String,
|
||||
pub cardinality: Cardinality,
|
||||
pub annotations: Vec<Annotation>,
|
||||
pub properties: Vec<PropDecl>,
|
||||
pub constraints: Vec<Constraint>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct PropDecl {
|
||||
pub name: String,
|
||||
pub prop_type: PropType,
|
||||
pub annotations: Vec<Annotation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Annotation {
|
||||
pub name: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
/// A typed constraint declared in a node or edge body.
|
||||
///
|
||||
/// Property-level annotations (`@key`, `@unique`, `@index`) are desugared
|
||||
/// into these during parsing, so both syntactic positions produce the same
|
||||
/// representation.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Constraint {
|
||||
Key(Vec<String>),
|
||||
Unique(Vec<String>),
|
||||
Index(Vec<String>),
|
||||
Range {
|
||||
property: String,
|
||||
min: Option<ConstraintBound>,
|
||||
max: Option<ConstraintBound>,
|
||||
},
|
||||
Check {
|
||||
property: String,
|
||||
pattern: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// A numeric bound used in `@range` constraints.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ConstraintBound {
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
}
|
||||
|
||||
/// Edge cardinality: `@card(min..max)`. Default is `0..*`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Cardinality {
|
||||
pub min: u32,
|
||||
pub max: Option<u32>,
|
||||
}
|
||||
|
||||
impl Default for Cardinality {
|
||||
fn default() -> Self {
|
||||
Self { min: 0, max: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl Cardinality {
|
||||
pub fn is_default(&self) -> bool {
|
||||
self.min == 0 && self.max.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_annotation(annotations: &[Annotation], name: &str) -> bool {
|
||||
annotations.iter().any(|ann| ann.name == name)
|
||||
}
|
||||
|
||||
pub fn annotation_value<'a>(annotations: &'a [Annotation], name: &str) -> Option<&'a str> {
|
||||
annotations
|
||||
.iter()
|
||||
.find(|ann| ann.name == name)
|
||||
.and_then(|ann| ann.value.as_deref())
|
||||
}
|
||||
2
crates/omnigraph-compiler/src/schema/mod.rs
Normal file
2
crates/omnigraph-compiler/src/schema/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub mod ast;
|
||||
pub mod parser;
|
||||
1950
crates/omnigraph-compiler/src/schema/parser.rs
Normal file
1950
crates/omnigraph-compiler/src/schema/parser.rs
Normal file
File diff suppressed because it is too large
Load diff
60
crates/omnigraph-compiler/src/schema/schema.pest
Normal file
60
crates/omnigraph-compiler/src/schema/schema.pest
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// Omnigraph Schema Grammar (.pg files)
|
||||
|
||||
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
|
||||
COMMENT = _{ LINE_COMMENT | BLOCK_COMMENT }
|
||||
LINE_COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }
|
||||
BLOCK_COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" }
|
||||
|
||||
schema_file = { SOI ~ schema_decl* ~ EOI }
|
||||
|
||||
schema_decl = { interface_decl | node_decl | edge_decl }
|
||||
|
||||
// interface Named { name: String @key }
|
||||
interface_decl = { "interface" ~ type_name ~ "{" ~ prop_decl* ~ "}" }
|
||||
|
||||
// node Person implements Named, Described { ... }
|
||||
node_decl = { "node" ~ type_name ~ annotation* ~ implements_clause? ~ "{" ~ (prop_decl | body_constraint)* ~ "}" }
|
||||
implements_clause = { "implements" ~ type_name ~ ("," ~ type_name)* }
|
||||
|
||||
// edge Knows: Person -> Person @card(0..1) { ... }
|
||||
// edge Knows: Person -> Person
|
||||
edge_decl = { "edge" ~ type_name ~ ":" ~ type_name ~ "->" ~ type_name ~ cardinality? ~ annotation* ~ ("{" ~ (prop_decl | body_constraint)* ~ "}")? }
|
||||
|
||||
// @card(0..1), @card(1..), @card(0..)
|
||||
cardinality = { "@card" ~ "(" ~ integer ~ ".." ~ integer? ~ ")" }
|
||||
|
||||
prop_decl = { ident ~ ":" ~ type_ref ~ annotation* }
|
||||
|
||||
// Body-level constraints: @key(name), @unique(a, b), @index(a, b), @range(age, 0..200), @check(code, "regex")
|
||||
body_constraint = { "@" ~ constraint_name ~ "(" ~ constraint_args ~ ")" }
|
||||
constraint_name = { "key" | "unique" | "index" | "range" | "check" }
|
||||
constraint_args = { constraint_arg ~ ("," ~ constraint_arg)* }
|
||||
constraint_arg = { range_bound | literal | ident }
|
||||
range_bound = { (signed_float | signed_integer) ~ ".." ~ (signed_float | signed_integer)? | ".." ~ (signed_float | signed_integer) }
|
||||
|
||||
type_ref = { core_type ~ "?"? }
|
||||
core_type = { list_type | enum_type | vector_type | base_type }
|
||||
list_type = { "[" ~ base_type ~ "]" }
|
||||
enum_type = { "enum" ~ "(" ~ enum_value ~ ("," ~ enum_value)* ~ ")" }
|
||||
vector_type = { "Vector" ~ "(" ~ integer ~ ")" }
|
||||
enum_value = @{ (ASCII_ALPHANUMERIC | "_" | "-")+ }
|
||||
|
||||
base_type = { "String" | "Blob" | "Bool" | "I32" | "I64" | "U32" | "U64" | "F32" | "F64" | "DateTime" | "Date" }
|
||||
|
||||
// Annotation rule excludes constraint keywords followed by "(" — those are body_constraints
|
||||
annotation = { "@" ~ !(constraint_name ~ "(") ~ ident ~ ("(" ~ annotation_arg ~ ")")? }
|
||||
annotation_arg = { literal | ident }
|
||||
|
||||
literal = { string_lit | float_lit | integer | bool_lit }
|
||||
|
||||
string_lit = @{ "\"" ~ string_char* ~ "\"" }
|
||||
string_char = @{ !("\"" | "\\") ~ ANY | "\\" ~ ANY }
|
||||
float_lit = @{ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ }
|
||||
integer = @{ ASCII_DIGIT+ }
|
||||
|
||||
signed_float = @{ "-"? ~ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ }
|
||||
signed_integer = @{ "-"? ~ ASCII_DIGIT+ }
|
||||
bool_lit = { "true" | "false" }
|
||||
|
||||
type_name = @{ ASCII_ALPHA_UPPER ~ (ASCII_ALPHANUMERIC | "_")* }
|
||||
ident = @{ (ASCII_ALPHA_LOWER | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
|
||||
Loading…
Add table
Add a link
Reference in a new issue