Quickstart
This guide walks you through creating a Spade block in Rust. By the end you will have a working block that reads a raster file, applies a resolution parameter, and writes the result.
Prerequisites🔗
- Rust stable toolchain
- Cargo package manager
- The Spade CLI installed (Installation guide)
Step 1: Create a block collection🔗
mkdir raster-tools && cd raster-tools
spade init --language rustThis scaffolds the project:
raster-tools/
Cargo.toml
src/
lib.rs
blocks/Add the Spade library:
cargo add spadeStep 2: Add a block🔗
spade add reprojectThis creates:
blocks/reproject.yaml-- the block manifestsrc/reproject.rs-- the handler entrypoint
Register the module in src/lib.rs or create src/main.rs with the entry point.
Step 3: Define the manifest🔗
Edit blocks/reproject.yaml:
id: raster-tools.reproject
version: 0.1.0
kind: standard
network: false
description: Reprojects a raster to a target resolution
inputs:
source:
type: file
format: GeoTIFF
resolution:
type: number
outputs:
raster:
type: file
format: GeoTIFFStep 4: Write the handler🔗
Edit src/main.rs:
use spade::{run, Args, RasterFile};
use std::process::Command;
fn handler(args: Args) -> Result<RasterFile, Box<dyn std::error::Error + Send + Sync>> {
let source: RasterFile = args.input("source")?;
let resolution: f64 = args.param("resolution")?;
let output_path = "reprojected.tif";
let status = Command::new("gdalwarp")
.args([
"-tr",
&resolution.to_string(),
&resolution.to_string(),
&source.path,
output_path,
])
.status()?;
if !status.success() {
return Err("gdalwarp failed".into());
}
Ok(RasterFile::new(output_path))
}
fn main() {
run(handler);
}Key concepts:
run(handler)is the main entry point. It loads inputs, parameters, calls your handler, and writes outputs.args.input::<T>(name)retrieves a typed file input.Tmust implement theFromInputtrait.args.param::<T>(name)retrieves a typed scalar parameter fromparams.yaml.Tmust implementserde::DeserializeOwned.- The handler returns
Result<O, Box<dyn Error + Send + Sync>>whereOimplementsIntoOutput + SpadeType.
Step 5: Validate and install🔗
spade check
spade install file://.Step 6: Use in a pipeline🔗
blocks:
- id: "@reproject"
name: raster-tools.reproject
inputs: []
args:
resolution: 10No-output handlers🔗
If your block performs a side effect without producing output, return ():
fn handler(args: Args) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let source: RasterFile = args.input("source")?;
println!("Validated: {}", source.path);
Ok(())
}
fn main() {
run(handler);
}The () type implements IntoOutput and SpadeType, so run() skips the output-writing step.
Next steps🔗
- Types -- all available Spade types
- Handler Functions -- handler patterns and multiple outputs
- Manifest Generation -- generating manifests with the builder API
- Examples -- complete worked examples