Expand description

Convert Rust structs with named fields into tables of output.

Django output pagination, filtering, and ordering is dealt with separately. This module is concerned with producing the individual formatted items in a Django query result, once those have been determined.

We are mimicking what is essentially a database query result encoded into JSON, with each row represented by an object, and each cell in that row being the value of a member of this object. The column names in this encoding are the names of the members of each of the row objects.

The IntoRow trait in this module is for converting an instance into a row within a table of output. The derive macro for this trait is an easy way to get an implementation for structs with named fields. Note that the values of the cells in a row cannot themselves be objects (this would effectively be a nested table), but they can be arrays. The CellValue type encodes this restriction.

A type which can be value of a particular column in a particular row should implement IntoCellValue. If the type implements Display and the desired JSON representation is a string, it’s simplest to derive the marker trait StringCellValue to benefit from a blanket derivation of IntoCellValue. Otherwise the trait must be implemented directly.

The concept of foreign keys in this module is a direct carryover from the database model we are emulating. Django results do not contain nested objects, instead one field of the nested object is chosen to represent the object - a foreign key. The AsForeignKey trait captures this idea.

Example:

use django_query::IntoRow;
use serde_json::json;
use std::sync::Arc;

#[derive(IntoRow)]
struct Foo {
  a: i32,
  #[django(foreign_key="a")]
  b: Option<Arc<Foo>>
}

let f1 = Arc::new(Foo { a: 1, b: None });
let f2 = Arc::new(Foo { a: 2, b: Some(f1.clone()) });
let f3 = Arc::new(Foo { a: 3, b: Some(f2.clone()) });

assert_eq!(f1.to_json(), json! {
  { "a": 1i32, "b": null }
});
assert_eq!(f2.to_json(), json! {
  { "a": 2i32, "b": 1i32 }
});
assert_eq!(f3.to_json(), json! {
  { "a": 3i32, "b": 2i32 }
});

Enums

The JSON types Django permits in cells - everything except object.

Traits

Something which can be stored in a cell by specifying one of its fields to stand in for it.

Something that can visit the values in a Django output row.

Something that can visit the columns that a Django output row sequence contains.

For things that can be converted into cell values within a Django output row.

Something that can be converted into a row in Django output.

Marker which means use Display to convert the type into a CellValue