flowchart TD
request["request<br>path to request.yaml"]
metadata["metadata<br>path to datapackage.json"]
output[/"Output<br>Result<(), CheckError>"/]
subgraph check ["check()"]
read_request["read_request()<br>Parse request into a Request struct"]
read_metadata["read_metadata()<br>Parse metadata file into a Package struct"]
check_package_name["check_package_name()<br>Package name matches metadata"]
check_package_version["check_package_version()<br>Package version matches metadata"]
check_resource_names["check_resource_names()<br>Resource names match metadata"]
check_column_names["check_column_names()<br>Column names match metadata"]
check_row_filters["check_row_filters()<br>Row filters match metadata columns"]
end
request --> read_request --> check_package_name --> check_package_version --> check_resource_names --> check_column_names --> check_row_filters --> output
metadata --> read_metadata --> check_package_name
check:::outer_function
classDef outer_function fill:none
Rust library interface
This document describes the design of the functions forming the Rust library and tracks the implementation status. All of these functions are external-facing functions that are used internally in the CLI commands.
We use symbols to indicate the status of implementation (see table below). For planned or in-progress work, we might include signatures, docstrings, and pseudocode to clarify the design. Once the interface is implemented, these are replaced by links to the reference documentation.
| Status | Description |
|---|---|
| Interface that has been implemented. | |
| Interface that is currently being worked on. | |
| Interface that is planned, but isn’t being worked on currently. |
read_package()
This function reads in the data package’s metadata file (currently only the datapackage.json file) into a Package struct. While we called it source in the args of many CLI commands, we call it package here to be clearer. “Source” on it’s own is a vague term, “source of what?”, so we wanted to be explicit that it is the data package’s metadata we are reading in. Plus, the struct is called Package. However, the read_package() has the argument called source, which is the location given in the SOURCE arg of many of the CLI commands.
At some point we aim to support other metadata formats, but for now only datapackage.json is supported.
The signature is (with an internal PackageSource enum for the different source locations):
read_package(source: PackageSource) -> Result<Package, Error>
read_request()
This reads in the request.yaml file into the Request struct. This functionality is very similar to read_package(). The signature is:
read_request(path: &str) -> Result<Request, Error>
check()
The check() function first reads and parses a request.yaml and a metadata file, datapackage.json, checking that they contain the required keys. It then runs the checks described below in order, returning a CheckError if any check fails.
/// Checks a request yaml against the metadata file.
///
/// The checks include:
///
/// - Required sections and keys are present in the request and metadata.
/// - Data package name and version in the request matches the metadata.
/// - The resources and columns in the request exist in the metadata.
/// - The row filters match columns in the metadata.
///
/// Errors if the request or metadata file can't be read, or if any
/// check fails.
pub fn check(request: Path, metadata: Path) -> Result<(), CheckError> {
let request = read_request(request);
let metadata = read_metadata(metadata);
// Package name and version matches metadata.
check_package_name(&request, &metadata);
check_package_version(&request, &metadata);
// Resource names match metadata.
check_resource_names(&request, &metadata);
// Column names match metadata.
check_column_names(&request, &metadata);
// Row filters match metadata columns (including whether the operator
// types and values are allowed with the column type).
check_row_filters(&request, &metadata);
Ok(())
}