Skip to content

Package Format

mafried edited this page Nov 22, 2023 · 18 revisions

Packages are used to describe available types (and nodes which are types as well) and reflect exactly the corresponding Rust packages (without describing all types in the Rust package). Types are described together with possible type arguments and constructors. The code generator that transforms flow project json files into Rust code uses this information.

Fields

The package format uses JSON syntax and contains the following elements:

Package:

  • name: The package name (type: String).
  • version: The package version (type: String, format: semantic versioning).
  • crates: The crates defined in this package. Crates reflect the structure of corresponding Rust crates (type: Dictionary of Crate objects (key: crate name, value: Crate object)).

Crate:

  • types: Types defined in this crate (type: Dictionary of Type objects (key: type name, value: Type object)).
  • modules: Modules defined in this crate. Modules reflect the structure of corresponding module crates (type: Dictionary of Module objects (key: module name, value: Module object)).

Module:

  • types: Types defined in this module (type: Dictionary of Type objects (key: type name, value: Type object)).
  • modules: Modules defined in this module (type: Dictionary of Module objects (key: module name, value: Module object)).

Type:

  • inputs: Optional list of input edges. If the type implements the Node trait, this needs to be set (type: Dictionary of TypeDescription objects (key: input name, value: TypeDescription object)).
  • outputs: Optional list of output edges. If the type implements the Node trait, this needs to be set (type: Dictionary of TypeDescription objects (key: output name, value: TypeDescription object)).
  • type_parameters: Optional list of type parameters in case the type is generic (type: List of Strings).
  • constructors: Constructors that can be used to create an instance of this type (type: Dictionary (key: constructor name, value: Constructor object)).

Constructor:

Reflects the flowrs_build::package::Constructor enumeration. Describes in detail how code for the constructor function should be created. The necessary fields depend on the enumeration type. Currently, the following types exist:

New

A simple constructor function without any parameters.

  • function_name: The optional name of the constructor function. Default: "new" (type: String).

NewWithObeserver

A simple constructor function with a single parameter being the globally available ChangeObserver object.

  • function_name: The optional name of the constructor function. Default: "new" (type: String).

Example:

"DebugNode":{
  ...
   "constructors":{
      "New":{
         "NewWithObserver":{
         
         }
      }
   }
}

NewWithObserverAndContext

A simple constructor function with two parameters: The globally available ChangeObserver and Context objects.

  • function_name: The optional name of the constructor function. Default: "new" (type: String).

NewWithArbitraryArgs

A constructor with arbitrary arguments.

  • function_name: The optional name of the constructor function. Default: "new" (type: String).
  • arguments: The arguments of the constructor function (type: List of Argument objects).

Argument:

  • name: The name of the argument (type: String).
  • type: The argument type (type: TypeDescription)
  • passing: Describes how the argument is passed to the constructor function (type: ArgumentPassing)
  • construction: Describes how the argument is constructed (type: ArgumentConstruction)

ArgumentPassing: Enumeration

  • Move
  • Clone
  • MutableReference
  • Reference

ArgumentConstruction: Enumeration

  • ExistingObject: One of the global objects (change_observer, context).
  • Constructor: Name of the constructor to use for argument construction (type: String).

TypeDescription: Enumeration

  • Type: A specific type (that can have additional type parameters).
    • name: Name of the type (type: String).
    • type_parameters: Optional list of type parameters (type: List of ArgumentType objects).
  • Generic: A generic type (that can have additional type parameters).
    • name: Name of the type (type: String).
    • type_parameters: Optional list of type parameters (type: List of ArgumentType objects).

Example:

{
   "ValueNode":{
      "outputs":{
         "output":{
            "type":{
               "Generic":{
                  "name":"I"
               }
            }
         }
      },
      "type_parameters":[
         "I"
      ],
      "constructors":{
         "New":{
            "NewWithArbitraryArgs":{
               "arguments":[
                  {
                     "type":{
                        "Generic":{
                           "name":"I"
                        }
                     },
                     "name":"value",
                     "passing":"Move",
                     "construction":{
                        "Constructor":"Json"
                     }
                  },
                  {
                     "type":{
                        "Type":{
                           "name":"()"
                        }
                     },
                     "name":"change_observer",
                     "passing":"Clone",
                     "construction":{
                        "ExistingObject":[
                           
                        ]
                     }
                  }
               ]
            }
         }
      }
   }
}

FromJson

A constructor that reads its arguments from JSON. The JSON is part of the flow project JSON.

Example:

"TimerNodeConfig":{
   "constructors":{
      "Json":"FromJson"
   }
}

FromDefault

A constructor that reads its arguments from JSON. The JSON is part of the flow project JSON.

Example:

"TimerNodeConfig":{
   "constructors":{
      "Default":"FromDefault"
   }
}

FromCode

A constructor that is directly written in Rust code.

  • code_template: The code that should be emitted for this constructor. The code can contain placeholders (marked with {{placeholder}}) that are replaced during code generation (type: String).

Possible placeholders:

  • fully_qualified_name: The fully qualified name of the object that should be created.
  • type_name: The name of the type.
  • type_parameter_part: The type parameter part of generic types.
  • type_parameter_NAME: The chosen type for type parameter NAME.
  • mutable: If the object to be created should be mutable, this field contains "mut". If not, it contains "".

Example:

"MyType":{
   "type_parameters":[
      "U",
      "T"
   ],
   "constructors":{
      "Code":{
         "FromCode":{
            "code_template":"let {{fully_qualified_name}}:{{type_parameter_U}} = 5;"
         }
      }
   }
}

Example

{
   "name":"flowrs-std",
   "version":"1.0.0",
   "crates":{
      "flowrs_std":{
         "types":{
            
         },
         "modules":{
            "nodes":{
               "types":{
                  
               },
               "modules":{
                  "debug":{
                     "modules":{
                        
                     },
                     "types":{
                        "DebugNode":{
                           "inputs":{
                              "input":{
                                 "type":{
                                    "Generic":{
                                       "name":"I"
                                    }
                                 }
                              }
                           },
                           "outputs":{
                              "output":{
                                 "type":{
                                    "Generic":{
                                       "name":"I"
                                    }
                                 }
                              }
                           },
                           "type_parameters":[
                              "I"
                           ],
                           "constructors":{
                              "New":{
                                 "NewWithObserver":{
                                    
                                 }
                              }
                           }
                        }
                     }
                  },
                  "value":{
                     "modules":{
                        
                     },
                     "types":{
                        "ValueType":{
                           "constructors":{
                              "Json":"FromJson"
                           }
                        },
                        "ValueNode":{
                           "outputs":{
                              "output":{
                                 "type":{
                                    "Generic":{
                                       "name":"I"
                                    }
                                 }
                              }
                           },
                           "type_parameters":[
                              "I"
                           ],
                           "constructors":{
                              "New":{
                                 "NewWithArbitraryArgs":{
                                    "arguments":[
                                       {
                                          "type":{
                                             "Generic":{
                                                "name":"I"
                                             }
                                          },
                                          "name":"value",
                                          "passing":"Move",
                                          "construction":{
                                             "Constructor":"Json"
                                          }
                                       },
                                       {
                                          "type":{
                                             "Type":{
                                                "name":"()"
                                             }
                                          },
                                          "name":"change_observer",
                                          "passing":"Clone",
                                          "construction":{
                                             "ExistingObject":[
                                                
                                             ]
                                          }
                                       }
                                    ]
                                 }
                              }
                           }
                        }
                     }
                  },
                  "timer":{
                     "modules":{
                        
                     },
                     "types":{
                        "TimerNodeConfig":{
                           "constructors":{
                              "Json":"FromJson"
                           }
                        },
                        "PollTimer":{
                           "type_parameters":[
                              "U"
                           ],
                           "constructors":{
                              "New":{
                                 "New":{
                                    
                                 }
                              }
                           }
                        },
                        "SelectedTimer":{
                           "type_parameters":[
                              "U"
                           ],
                           "constructors":{
                              "New":{
                                 "New":{
                                    
                                 }
                              }
                           }
                        },
                        "TimerNode":{
                           "inputs":{
                              "config_input":{
                                 "type":{
                                    "Type":{
                                       "name":"flowrs_std::nodes::timer::TimerNodeConfig"
                                    }
                                 }
                              },
                              "token_input":{
                                 "type":{
                                    "Generic":{
                                       "name":"U"
                                    }
                                 }
                              }
                           },
                           "outputs":{
                              "token_output":{
                                 "type":{
                                    "Generic":{
                                       "name":"U"
                                    }
                                 }
                              }
                           },
                           "type_parameters":[
                              "T",
                              "U"
                           ],
                           "constructors":{
                              "NewWithToken":{
                                 "NewWithArbitraryArgs":{
                                    "function_name":"new_with_token",
                                    "arguments":[
                                       {
                                          "type":{
                                             "Generic":{
                                                "name":"T",
                                                "type_parameters":[
                                                   {
                                                      "Generic":{
                                                         "name":"U"
                                                      }
                                                   }
                                                ]
                                             }
                                          },
                                          "name":"timer",
                                          "passing":"Move",
                                          "construction":{
                                             "Constructor":"New"
                                          }
                                       },
                                       {
                                          "type":{
                                             "Generic":{
                                                "name":"U"
                                             }
                                          },
                                          "name":"token_object",
                                          "passing":"Move",
                                          "construction":{
                                             "Constructor":"New"
                                          }
                                       },
                                       {
                                          "type":{
                                             "Type":{
                                                "name":"()"
                                             }
                                          },
                                          "name":"change_observer",
                                          "passing":"Clone",
                                          "construction":{
                                             "ExistingObject":[
                                                
                                             ]
                                          }
                                       }
                                    ]
                                 }
                              },
                              "New":{
                                 "NewWithArbitraryArgs":{
                                    "arguments":[
                                       {
                                          "type":{
                                             "Generic":{
                                                "name":"T",
                                                "type_parameters":[
                                                   {
                                                      "Generic":{
                                                         "name":"U"
                                                      }
                                                   }
                                                ]
                                             }
                                          },
                                          "name":"timer",
                                          "passing":"Move",
                                          "construction":{
                                             "Constructor":"New"
                                          }
                                       },
                                       {
                                          "type":{
                                             "Type":{
                                                "name":"()"
                                             }
                                          },
                                          "name":"change_observer",
                                          "passing":"Clone",
                                          "construction":{
                                             "ExistingObject":[
                                                
                                             ]
                                          }
                                       }
                                    ]
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

How-Tos

How-To: Create a new flow package

For creating a new flow package, add a new JSON file to the flow-packages folder (in florws-build/flow-packages). It should have the same name and version like the corresponding Rust package (e.g. flowrs-std.json for the flowrs-std package). Flow packages directly map to Rust packages and reflect their structure. That means e.g. that crates in the Rust package have their counterpart in the flow package JSON:

{
   "name":"flowrs-std",
   "version":"1.0.0",
   "crates":{
      "flowrs_std":{
        ...
   }
}

Like Rust crates, flow crates can have modules (which can contain modules) and types. See for example the type DebugNode:

{
   "name":"flowrs-std",
   "version":"1.0.0",
   "crates":{
      "flowrs_std":{
         "types":{
            
         },
         "modules":{
            "nodes":{
               "types":{
                  
               },
               "modules":{
                  "debug":{
                     "modules":{
                        "types":{
                           "DebugNode":{
                          
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

It directly reflects the definition of the Rust struct DebugNode whose full Rust name is flowrs_std::nodes::debug::DebugNode (see also flowrs-std/nodes/debug.rs). BTW: Nodes are also types which contain additional input and output declarations. If a certain type should be instantiated within the initialization of a flow (like nodes used in the flow or constructor parameters of that nodes) it must be defined in a flow package.

How-To: Add a new simple type to a flow package

Let's say we want to add a new type named "ValueType" that should be instantiated using a JSON constructor. We choose a module in the flow package (based on the location of the corresponding Rust struct) and add to its "types" dictionary our new type:

 "ValueType":{
      "constructors":{
         "Json":"FromJson"
      }
   }

It has a constructor named "Json" that is of type "FromJson" which means the type can be instantiated using JSON-encoded input data (which is defined in the flow project JSON's "data" field). If the type just has a simple "new" constructor without parameters, one would define a constructor of type "New":

 "ValueType":{
      "constructors":{
         "New":"New"
      }
   }

Node types often have constructors with a single argument, the change_observer. Defining this constructor is easy:

 "ValueType":{
      "constructors":{
         "New":{"NewWithObserver": {}},
      }
   }

If a node type has a constructor with an additional context parameter, another pre-defined constructor exists:

 "ValueType":{
      "constructors":{
         "New":{"NewWithObserverAndContext": {}},
      }
   }

If a type implements the default trait, a constructor of type "FromDefault" can be added.

Clone this wiki locally