From d2c1e1ca6b376be037da3e8f1fadf581c567c752 Mon Sep 17 00:00:00 2001 From: Emil Eriksson <8700261+ginger51011@users.noreply.github.com> Date: Fri, 10 Feb 2023 19:51:17 +0100 Subject: [PATCH] Add minimal documentation to in `ir` in `trustfall_core` (#139) * Add minimal documentation to in * Fix rustfmt * Update trustfall_core/src/ir/mod.rs Better IRQueryComponent docs Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> * Fix conflict * Update trustfall_core/src/ir/mod.rs --------- Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> --- trustfall_core/src/interpreter/execution.rs | 2 +- trustfall_core/src/ir/mod.rs | 30 +++++++++++++++++++-- trustfall_core/src/ir/value.rs | 16 ++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/trustfall_core/src/interpreter/execution.rs b/trustfall_core/src/interpreter/execution.rs index 49e42062..d7b22b29 100644 --- a/trustfall_core/src/interpreter/execution.rs +++ b/trustfall_core/src/interpreter/execution.rs @@ -611,7 +611,7 @@ fn compute_fold<'query, DataToken: Clone + Debug + 'query>( /// /// A small subtlety is important here: it's possible that the tagged value is *local* to /// the scope being filtered. In that case, the context *will not* yet have a token associated -/// with the vertex ID of the tag's ContextField. However, in such cases, the tagged value +/// with the [Vid] of the tag's ContextField. However, in such cases, the tagged value /// is *never* optional relative to the current scope, so we can safely return `false`. #[inline(always)] fn is_tag_optional_and_missing<'query, DataToken: Clone + Debug + 'query>( diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index 3448798c..65941ee8 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -1,3 +1,4 @@ +//! Trustfall intermediate representation (IR) #![allow(dead_code)] pub mod indexed; @@ -26,8 +27,10 @@ lazy_static! { pub(crate) static ref TYPENAME_META_FIELD_ARC: Arc = Arc::from(TYPENAME_META_FIELD); } +/// Vertex ID +#[doc(alias("vertex", "node"))] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] -pub struct Vid(pub(crate) NonZeroUsize); // vertex ID +pub struct Vid(pub(crate) NonZeroUsize); impl Vid { pub fn new(id: NonZeroUsize) -> Vid { @@ -35,8 +38,10 @@ impl Vid { } } +/// Edge ID +#[doc(alias = "edge")] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] -pub struct Eid(pub(crate) NonZeroUsize); // edge ID +pub struct Eid(pub(crate) NonZeroUsize); impl Eid { pub fn new(id: NonZeroUsize) -> Eid { @@ -49,8 +54,13 @@ pub struct EdgeParameters( #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub BTreeMap, FieldValue>, ); +/// A complete component of a query; may itself contain one or more components. +/// +/// Contains information about the Vid where the component is rooted, +/// as well as well as maps of all vertices, edges, folds, and outputs from this component. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct IRQueryComponent { + /// The [Vid] of the root, or entry point, of the component. pub root: Vid, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] @@ -66,6 +76,7 @@ pub struct IRQueryComponent { pub outputs: BTreeMap, ContextField>, } +/// Intermediate representation of a query #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct IRQuery { pub root_name: Arc, @@ -94,6 +105,9 @@ pub struct IREdge { #[serde(default, skip_serializing_if = "Option::is_none")] pub parameters: Option>, + /// Indicating if this edge is optional. + /// + /// Corresponds to the `@optional` directive. #[serde(default = "default_optional", skip_serializing_if = "is_false")] pub optional: bool, @@ -123,9 +137,13 @@ impl Recursive { } } +/// Representation of a vertex (node) in the Trustfall intermediate +/// representation (IR). #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct IRVertex { pub vid: Vid, + + /// The name of the type of the vertex as a string. pub type_name: Arc, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -282,6 +300,13 @@ impl Argument { } } +/// Operations that can be made in the graph. +/// +/// In a Trustfall query, the `@filter` directive produces `Operation` values: +/// ```graphql +/// name @filter(op: "=", values: ["$input"]) +/// ``` +/// would produce the `Operation::Equals` variant, for example. #[non_exhaustive] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Operation @@ -365,6 +390,7 @@ where } } + /// The operation name, as it would have appeared in the `@filter` directive `op` argument. pub(crate) fn operation_name(&self) -> &'static str { match self { Operation::IsNull(..) => "is_null", diff --git a/trustfall_core/src/ir/value.rs b/trustfall_core/src/ir/value.rs index ec5c4917..a5cadb51 100644 --- a/trustfall_core/src/ir/value.rs +++ b/trustfall_core/src/ir/value.rs @@ -1,7 +1,11 @@ +/// IR of the values of Trustfall fields. use async_graphql_value::{ConstValue, Number, Value}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +/// Values of fields in Trustfall. +/// +/// For version that is serialized as an untagged enum, see [TransparentValue]. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum FieldValue { // Order may matter here! Deserialization, if ever configured for untagged serialization, @@ -10,9 +14,11 @@ pub enum FieldValue { // This is because we want to prioritize the standard Integer GraphQL type over our custom u64, // and prioritize exact integers over lossy floats. Null, - Int64(i64), // AKA Integer + /// AKA integer + Int64(i64), Uint64(u64), - Float64(f64), // AKA Float, and also not allowed to be NaN + /// AKA Float, and also not allowed to be NaN + Float64(f64), String(String), Boolean(bool), DateTimeUtc(DateTime), @@ -20,7 +26,9 @@ pub enum FieldValue { List(Vec), } -/// Same as FieldValue, but serialized as an untagged enum, +/// Values of fields in GraphQL types. +/// +/// Same as [FieldValue], but serialized as an untagged enum, /// which may be more suitable e.g. when serializing to JSON. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -190,6 +198,7 @@ impl From for FieldValue { } } +/// Represents a finite (non-infinite, not-NaN) [f64] value pub struct FiniteF64(f64); impl From for FieldValue { fn from(f: FiniteF64) -> FieldValue { @@ -320,6 +329,7 @@ impl> From<&[T]> for FieldValue { } } +/// Converts a JSON number to a [FieldValue] fn convert_number_to_field_value(n: &Number) -> Result { // The order here matters! // Int64 must be before Uint64, which must be before Float64.