Rust types for followthemoney
Warning
In development. Use at your own risk. Can suddenly swerve. Entities in mirror are larger than they appear 😳
Tip
Suggestions welcome. Especially in terms of ergonomics and tooling.
This is a library crate attempting to generate Rust structs and helpers based on opensanctions/followthemoney schema definitions.
The binary application in this crate downloads FTM YAML schemas from the opensanctions/followthemoney repository and generates structs for entities, one large Enum and a bunch of helpers.
At this moment this is an experiment, an attempt to bring the Python followthemoney API to Rust. Hopefully it enables upcoming Rust applications to be compatible with OpenAleph, OpenSanctions, and other opensanctions/followthemoney-based tools.
Add to your Cargo.toml:
[dependencies]
ftm-types = "0.1"And start exploring:
use ftm_types::generated::FtmEntity;$ just download-ftm-schema 4.5.0
$ cargo run -- 4.5.0The library offers one struct per ftm schema:
// Generated entity structs with all properties flattened
pub struct Person {
pub id: String,
pub schema: String,
pub name: Option<Vec<String>>,
pub birth_date: Option<Vec<String>>,
pub nationality: Option<Vec<String>>,
// ... all properties from parent schemas flattened
}
but also a Trait for polymorphism:
// Traits for polymorphic code
pub trait Thing {
fn id(&self) -> &str;
fn name(&self) -> Option<&[String]>;
fn country(&self) -> Option<&[String]>;
// ... methods for all Thing properties
}
and implementations of it:
// Concrete types implement parent traits
impl Thing for Person {
fn id(&self) -> &str { &self.id }
fn name(&self) -> Option<&[String]> { self.name.as_deref() }
// ...
}
and then one Enum with all the entity types:
// Enum for runtime polymorphism
pub enum FtmEntity {
Person(Person),
Organization(Organization),
Company(Company),
// ... all entity types
}The library uses a hybrid approach: entity structs have flat structures for direct access, but also implement traits for polymorphic code. See also examples/first_steps.rs by running:
$ cargo run --example trait_polymorphism.rsFTM types are mapped to Rust types as follows:
| FTM Type | Rust Type |
|---|---|
name, text, string |
Option<Vec<String>> |
number |
Option<Vec<f64>> |
date |
Option<Vec<String>> |
json |
Option<serde_json::Value> |
country, email, etc. |
Option<Vec<String>> |
All properties are multi-valued by default (following FTM semantics) and optional (unless required).
builderuses Bon to generate a builder API. The builder will respect therequiredfields in the schema. Check out the example code.
MIT OR Apache-2.0