From d135da30544bb8f6777c5de85ab02475dd590524 Mon Sep 17 00:00:00 2001 From: Emil Jonathan Eriksson Date: Fri, 10 Feb 2023 09:01:18 +0100 Subject: [PATCH 1/6] Add minimal documentation to in --- trustfall_core/src/ir/mod.rs | 34 ++++++++++++++++++++++++++++++++-- trustfall_core/src/ir/value.rs | 17 ++++++++++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index 3448798c..53742341 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -1,3 +1,4 @@ +//! Trustfall internal 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,12 @@ pub struct EdgeParameters( #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub BTreeMap, FieldValue>, ); +/// IR of components of a query, containing information about the vertex ID +/// of the root of the query, as well as well as maps of all vertices, edges, +/// folds, and outputs of the query. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct IRQueryComponent { + /// The [Vid] of the root, or entry point, of the query. pub root: Vid, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] @@ -66,6 +75,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 +104,9 @@ pub struct IREdge { #[serde(default, skip_serializing_if = "Option::is_none")] pub parameters: Option>, + /// Indicating if this edge is optional. + /// + /// This would correspond to `@optional` in GraphQL. #[serde(default = "default_optional", skip_serializing_if = "is_false")] pub optional: bool, @@ -123,9 +136,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 +299,15 @@ impl Argument { } } +/// Operations that can be made in the graph. +/// +/// In GraphQL, this can correspond to the `op` argument in `@filter`, +/// for example in the following: +/// ```graphql +/// query Student { +/// name @filter(op: "has_substring", values: ["John"]) +/// } +/// ``` #[non_exhaustive] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Operation @@ -365,6 +391,10 @@ where } } + /// The operation name as a `str` + /// + /// Note that these are the same as would be given to a GraphQL `op` + /// argumetn. 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..3d035faf 100644 --- a/trustfall_core/src/ir/value.rs +++ b/trustfall_core/src/ir/value.rs @@ -1,7 +1,12 @@ +/// IR of the values of GraphQL fields. + use async_graphql_value::{ConstValue, Number, Value}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +/// Values of fields in GraphQL types. +/// +/// 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 +15,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 +27,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 +199,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 +330,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. From 464fa9d353e809fa972e1f24204a8a10d67845f3 Mon Sep 17 00:00:00 2001 From: Emil Jonathan Eriksson Date: Fri, 10 Feb 2023 09:06:33 +0100 Subject: [PATCH 2/6] Fix rustfmt --- trustfall_core/src/ir/mod.rs | 8 ++++---- trustfall_core/src/ir/value.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index 53742341..bb936870 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -105,7 +105,7 @@ pub struct IREdge { pub parameters: Option>, /// Indicating if this edge is optional. - /// + /// /// This would correspond to `@optional` in GraphQL. #[serde(default = "default_optional", skip_serializing_if = "is_false")] pub optional: bool, @@ -141,7 +141,7 @@ impl Recursive { #[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, @@ -300,7 +300,7 @@ impl Argument { } /// Operations that can be made in the graph. -/// +/// /// In GraphQL, this can correspond to the `op` argument in `@filter`, /// for example in the following: /// ```graphql @@ -392,7 +392,7 @@ where } /// The operation name as a `str` - /// + /// /// Note that these are the same as would be given to a GraphQL `op` /// argumetn. pub(crate) fn operation_name(&self) -> &'static str { diff --git a/trustfall_core/src/ir/value.rs b/trustfall_core/src/ir/value.rs index 3d035faf..505cfb0b 100644 --- a/trustfall_core/src/ir/value.rs +++ b/trustfall_core/src/ir/value.rs @@ -1,11 +1,10 @@ /// IR of the values of GraphQL fields. - use async_graphql_value::{ConstValue, Number, Value}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; /// Values of fields in GraphQL types. -/// +/// /// For version that is serialized as an untagged enum, see [TransparentValue]. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum FieldValue { From bf2ea7b10b15ff33195950febc6c94466e314529 Mon Sep 17 00:00:00 2001 From: Emil Eriksson <8700261+ginger51011@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:38:26 +0100 Subject: [PATCH 3/6] Update trustfall_core/src/ir/mod.rs Better IRQueryComponent docs Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> --- trustfall_core/src/ir/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index bb936870..87655cd5 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -54,9 +54,10 @@ pub struct EdgeParameters( #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub BTreeMap, FieldValue>, ); -/// IR of components of a query, containing information about the vertex ID -/// of the root of the query, as well as well as maps of all vertices, edges, -/// folds, and outputs of the query. +/// 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 query. From 239fd1c8b3de850a922262d854f456fb91f7b03f Mon Sep 17 00:00:00 2001 From: Emil Eriksson <8700261+ginger51011@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:41:48 +0100 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> --- trustfall_core/src/ir/mod.rs | 20 ++++++++------------ trustfall_core/src/ir/value.rs | 4 ++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index 87655cd5..c1e6596b 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -1,4 +1,4 @@ -//! Trustfall internal representation (IR) +//! Trustfall intermediate representation (IR) #![allow(dead_code)] pub mod indexed; @@ -60,7 +60,7 @@ pub struct EdgeParameters( /// 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 query. + /// The [Vid] of the root, or entry point, of the component. pub root: Vid, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] @@ -107,7 +107,7 @@ pub struct IREdge { /// Indicating if this edge is optional. /// - /// This would correspond to `@optional` in GraphQL. + /// Corresponds to the `@optional` directive. #[serde(default = "default_optional", skip_serializing_if = "is_false")] pub optional: bool, @@ -302,12 +302,11 @@ impl Argument { /// Operations that can be made in the graph. /// -/// In GraphQL, this can correspond to the `op` argument in `@filter`, -/// for example in the following: +/// In a Trustfall query, the `@filter` directive produces `Operation` values: /// ```graphql -/// query Student { -/// name @filter(op: "has_substring", values: ["John"]) -/// } +/// name @filter(op: "=", values: ["$input"]) +/// ``` +/// would produce the `Operation::Equals` variant, for example. /// ``` #[non_exhaustive] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -392,10 +391,7 @@ where } } - /// The operation name as a `str` - /// - /// Note that these are the same as would be given to a GraphQL `op` - /// argumetn. + /// 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 505cfb0b..a5cadb51 100644 --- a/trustfall_core/src/ir/value.rs +++ b/trustfall_core/src/ir/value.rs @@ -1,9 +1,9 @@ -/// IR of the values of GraphQL fields. +/// 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 GraphQL types. +/// Values of fields in Trustfall. /// /// For version that is serialized as an untagged enum, see [TransparentValue]. #[derive(Debug, Clone, Serialize, Deserialize)] From b0ae0e55bc2fbacc36b6663846619bcb30114a4b Mon Sep 17 00:00:00 2001 From: Emil Jonathan Eriksson Date: Fri, 10 Feb 2023 17:44:12 +0100 Subject: [PATCH 5/6] Fix conflict --- trustfall_core/src/interpreter/execution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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>( From d7b12360a65043c21a00524b0345a8d8034801b5 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:48:01 -0500 Subject: [PATCH 6/6] Update trustfall_core/src/ir/mod.rs --- trustfall_core/src/ir/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/trustfall_core/src/ir/mod.rs b/trustfall_core/src/ir/mod.rs index c1e6596b..65941ee8 100644 --- a/trustfall_core/src/ir/mod.rs +++ b/trustfall_core/src/ir/mod.rs @@ -307,7 +307,6 @@ impl Argument { /// 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