pub struct FieldMapping {
pub source: String,
pub output: String,
pub source_fallback: Option<String>,
pub nested_typename: Option<String>,
pub nested_fields: Option<Vec<FieldMapping>>,
pub declared_scalar: bool,
}Expand description
Field mapping for projection with alias support.
Fields§
§source: StringJSONB key name (source).
output: StringOutput key name (alias if different from source).
source_fallback: Option<String>Fallback stored key, tried when source is not present in the row.
Populated by every constructor from stored_key_candidates. It is not
support for camelCase storage — a view exposes snake_case keys and
columns, and the SQL projection generator has no fallback at all. It is
there because this projector runs over two different maps: the raw
stored document, whose keys are snake_case, and the output of
jsonb_build_object, whose keys are the camelCase response names the
SQL projection already emitted. One mapping has to read both.
Until #1271 this field had no producer anywhere in the workspace —
its documented job was described and never performed, and the primary
source was the declared name verbatim, so the raw-document case was
simply unreadable.
nested_typename: Option<String>For nested object fields, the typename to add.
This enables __typename to be added recursively to nested objects.
nested_fields: Option<Vec<FieldMapping>>Nested field mappings (for related objects).
declared_scalar: boolThe schema positively declares this field a scalar (#1192).
Set by ProjectionMapper::with_declared_scalars, which is the only
thing that knows. It gates the JSON-text re-parse below: a value the
database handed back as a string is re-read as an object or an array when
it parses as one, to recover a nested object the SQL side extracted with
->> — and the comment justifying that said scalar strings “won’t parse
as Object/Array, so this is safe for all field types”. That premise is
false for exactly the rows a text column full of serialized JSON exists
to carry: an audit payload, a webhook body, an imported document. A field
declared String was returned as the value its text encodes, so the
response violated the schema the server publishes, per row, depending on
whether that row’s text happened to parse.
Defaults to false — not known to be scalar — so a mapping built
without schema knowledge keeps the recovery behaviour it had.
Implementations§
Source§impl FieldMapping
impl FieldMapping
Sourcepub fn simple(name: impl Into<String>) -> Self
pub fn simple(name: impl Into<String>) -> Self
Create a simple field mapping (no alias).
name is the declared field name; the stored key it reads is
derived by stored_key_candidates, not taken verbatim.
let mapping = FieldMapping::simple("fkUser");
assert_eq!(mapping.source, "fk_user");
assert_eq!(mapping.output, "fkUser");Sourcepub fn aliased(source: impl Into<String>, alias: impl Into<String>) -> Self
pub fn aliased(source: impl Into<String>, alias: impl Into<String>) -> Self
Create a field mapping with an alias.
source is the declared field name and alias the response key —
the same split the SQL projection generator makes, where an aliased
field myName: fullName reads data->>'full_name' and is emitted as
myName (#418). The stored key is derived from source by
stored_key_candidates.
Sourcepub fn nested_object(
name: impl Into<String>,
typename: impl Into<String>,
fields: Vec<FieldMapping>,
) -> Self
pub fn nested_object( name: impl Into<String>, typename: impl Into<String>, fields: Vec<FieldMapping>, ) -> Self
Create a field mapping for a nested object with its own typename.
§Example
// For a Post with nested author (User type)
let mapping = FieldMapping::nested_object("author", "User", vec![
FieldMapping::simple("id"),
FieldMapping::simple("name"),
]);
assert_eq!(mapping.source, "author");Sourcepub fn nested_object_aliased(
source: impl Into<String>,
alias: impl Into<String>,
typename: impl Into<String>,
fields: Vec<FieldMapping>,
) -> Self
pub fn nested_object_aliased( source: impl Into<String>, alias: impl Into<String>, typename: impl Into<String>, fields: Vec<FieldMapping>, ) -> Self
Create an aliased nested object field.
Sourcepub fn with_nested_typename(self, typename: impl Into<String>) -> Self
pub fn with_nested_typename(self, typename: impl Into<String>) -> Self
Set the typename for a nested object field.
Sourcepub fn with_nested_fields(self, fields: Vec<FieldMapping>) -> Self
pub fn with_nested_fields(self, fields: Vec<FieldMapping>) -> Self
Set nested field mappings.