pub enum RecordTransform {
Flatten {
separator: String,
},
RenameKeys {
pattern: String,
replacement: String,
},
KeysCase {
mode: KeyCaseMode,
},
Select {
fields: Vec<String>,
},
Drop {
fields: Vec<String>,
},
Set {
values: Map<String, Value>,
},
RenameField {
fields: HashMap<String, String>,
},
Cast {
fields: HashMap<String, CastType>,
on_error: CastOnError,
},
Redact {
fields: Vec<String>,
mask: Value,
},
ValueCase {
fields: Vec<String>,
mode: ValueCaseMode,
},
SpellSymbols {
extra: HashMap<String, String>,
separator: String,
},
Custom(Arc<dyn Fn(Value) -> Value + Send + Sync>),
}Expand description
A transformation applied to every record fetched by a source (e.g. the REST
source’s RestStream).
Transforms are applied in the order they are added via the owning source’s
configuration (e.g. RestStreamConfig::add_transform).
The three built-in variants are each guarded by a Cargo feature flag
(all enabled by default — see module-level docs).
RecordTransform::Custom is always available and accepts any closure.
Variants§
Flatten
transform-flatten only.Flatten nested JSON objects into a single-level map.
Nested key paths are joined with separator. Arrays are left as-is.
Requires feature transform-flatten (default).
§Example
{"user": {"id": 1, "addr": {"city": "NYC"}}} → (separator = "__")
{"user__id": 1, "user__addr__city": "NYC"}RenameKeys
transform-rename-keys only.Apply a single regex substitution to every key in the record.
Keys in nested objects and objects inside arrays are also renamed
recursively. pattern is a Rust regex; replacement may reference
capture groups with $1, ${name}, etc. Chain multiple RenameKeys
transforms for multi-step pipelines.
Requires feature transform-rename-keys (default).
§Example
pattern = r"^_sdc_", replacement = "" → strip "_sdc_" prefixKeysCase
transform-keys-case only.Re-case every key in the record according to mode.
Tokenises each key on whitespace, _, -, dropped punctuation, and
lower→upper transitions, then re-joins in the requested convention.
Walks recursively into nested objects and arrays. Two distinct keys
that re-case to the same name error rather than silently overwriting.
Requires feature transform-keys-case (default).
| Input | Snake | Camel | Pascal | Kebab | ScreamingSnake |
|---|---|---|---|---|---|
"First Name" | "first_name" | "firstName" | "FirstName" | "first-name" | "FIRST_NAME" |
"last-name" | "last_name" | "lastName" | "LastName" | "last-name" | "LAST_NAME" |
"camelCase" | "camel_case" | "camelCase" | "CamelCase" | "camel-case" | "CAMEL_CASE" |
Fields
mode: KeyCaseModeSelect
transform-select only.Keep only the listed top-level fields on each record; remove the rest.
Missing fields are silently skipped (they don’t introduce nulls).
Non-object records pass through unchanged.
Requires feature transform-select.
Drop
transform-drop only.Remove the listed top-level fields from each record.
Missing fields are silently skipped. Non-object records pass through.
Requires feature transform-drop.
Set
transform-set only.Insert or overwrite top-level fields on each record with constant values.
Existing fields with the same name are overwritten. Non-object records pass through unchanged.
Requires feature transform-set.
RenameField
transform-rename-field only.Exact-name rename of one or more top-level fields.
Unlike RecordTransform::RenameKeys (regex, recursive), this only
touches exact top-level keys. Missing source fields are silently skipped.
If a target name already exists on the record, the rename errors rather
than silently overwriting.
Requires feature transform-rename-field.
Cast
transform-cast only.Coerce per-field types on each record.
Each named field is converted to the matching CastType. The
CastOnError policy controls failure behaviour. Missing fields are
silently skipped (no nulls introduced).
Requires feature transform-cast.
Redact
transform-redact only.Replace each listed field’s value with a constant mask.
Missing fields are silently skipped (no mask inserted). Default mask is
"***" when constructed from CLI config.
Requires feature transform-redact.
ValueCase
transform-value-case only.Lowercase / uppercase / trim string values on listed fields.
Non-string field values pass through unchanged. Missing fields are silently skipped.
Requires feature transform-value-case.
SpellSymbols
transform-spell-symbols only.Recursively spell out symbols inside every key with their word
equivalents (% → percent, # → number, $ → dollar, …).
Built-in defaults cover the common ASCII symbols (see
default_symbol_map); extra adds or overrides entries. Each
replacement is surrounded by separator (default " ") so a chained
RecordTransform::KeysCase picks up the word boundary.
Keys are walked recursively into nested objects and arrays, mirroring
the existing key-shape transforms. Two distinct keys that collapse to
the same name error rather than silently overwriting.
Requires feature transform-spell-symbols.
§Example
{"% sold": 1, "C# courses": 2}
→ (defaults, separator=" ")
{" percent sold": 1, "C number courses": 2}Fields
extra: HashMap<String, String>Additional mappings (merged on top of default_symbol_map;
entries with the same from override the default).
Custom(Arc<dyn Fn(Value) -> Value + Send + Sync>)
A user-supplied transformation function.
The function receives each record as a Value and returns the
(possibly modified) record. Construct one with RecordTransform::custom.
Always available — not guarded by any feature flag.
Implementations§
Source§impl RecordTransform
impl RecordTransform
Sourcepub fn custom<F>(f: F) -> Self
pub fn custom<F>(f: F) -> Self
Create a custom transform from any function or closure.
The closure receives each record as a Value and must return a
Value (the transformed record). It is called once per record and
may perform any manipulation — adding fields, removing fields, renaming,
type coercion, etc.
Custom transforms are always available regardless of feature flags.
§Example
use faucet_core::RecordTransform;
use serde_json::{Value, json};
// Inject a constant "source" field into every record.
let stamp = RecordTransform::custom(|mut record| {
if let Value::Object(ref mut map) = record {
map.insert("_source".to_string(), json!("my-api"));
}
record
});