Skip to main content

ArraySpec

Struct ArraySpec 

Source
pub struct ArraySpec {
    pub of: Box<Field>,
    pub count: Option<Count>,
}
Expand description

Specification for generating JSON arrays in JGD (JSON Generator Definition) schemas.

ArraySpec defines how to generate arrays of elements, including the type of elements to generate and how many elements the array should contain. It provides a flexible way to create arrays with consistent element types and configurable cardinality.

§JGD Schema Integration

Arrays are a fundamental data structure in JGD schemas, used to represent collections of similar items. The ArraySpec corresponds to the array field type in JGD schema specifications.

§Components

  • Element Specification: Defines what type of elements to generate (of field)
  • Count Specification: Defines how many elements to generate (count field)

§JSON Schema Representation

In a JGD schema, an array specification is represented as:

{
  "array": {
    "of": "${name.firstName}",
    "count": 5
  }
}

Or with a range count:

{
  "array": {
    "of": {
      "number": {
        "min": 1,
        "max": 100,
        "integer": true
      }
    },
    "count": [3, 8]
  }
}

§Element Types

The of field can specify any valid JGD field type:

  • Primitive types (strings, numbers, booleans)
  • Complex types (objects, nested arrays)
  • Fake data specifications
  • Optional types

§Count Behavior

  • Specified Count: Uses the provided count specification
  • Default Count: When omitted, defaults to generating 1 element
  • Range Counts: Randomly selects count within the specified range
  • Fixed Counts: Always generates exactly the specified number

§Examples

use jgd_rs::{ArraySpec, Field, Count, JsonGenerator, GeneratorConfig};
use serde_json::json;

let mut config = GeneratorConfig::new("EN", Some(42));

// Array of 5 strings with fake data template
let string_array = ArraySpec {
    of: Box::new(Field::Str("${name.firstName}".to_string())),
    count: Some(Count::Fixed(5)),
};

let result = string_array.generate(&mut config);
// Generates: ["John", "Jane", "Bob", "Alice", "Charlie"]

// Array with variable count using numbers
let number_array = ArraySpec {
    of: Box::new(Field::Number {
        number: NumberSpec::new_integer(1.0, 100.0)
    }),
    count: Some(Count::Range((2, 6))),
};

let result = number_array.generate(&mut config);
// Generates: [42, 17, 89] (length between 2-6)

§Performance Considerations

  • Pre-allocates the vector with the known capacity for efficiency
  • Generates elements sequentially to maintain deterministic ordering
  • Memory usage scales linearly with the generated count

§Use Cases

  • User Lists: Generate arrays of user profiles or contact information
  • Product Catalogs: Create collections of product specifications
  • Transaction Records: Generate sequences of financial transactions
  • Test Data: Create realistic datasets for application testing
  • Mock APIs: Provide dynamic array responses for API development

Fields§

§of: Box<Field>

The specification for elements that will populate the array.

This field defines the type and generation rules for each element in the generated array. All elements in the array will be generated according to this specification, ensuring type consistency throughout the array.

The field is boxed to allow for recursive type definitions (arrays of arrays) and to keep the ArraySpec struct size manageable.

§Element Generation

Each element is generated independently using this specification, which means:

  • Fake data will produce different values for each element
  • Random numbers will vary across elements (with proper seeding)
  • Optional fields may be present or absent independently

§Supported Types

Any valid Field type can be used as the element specification:

  • Field::Str for text arrays
  • Field::Number for numeric arrays
  • Field::Entity for object arrays
  • Field::Array for nested array structures
  • Field::Optional for arrays with nullable elements

§JSON Schema Mapping

Maps to the of property in JGD array specifications:

{
  "array": {
    "of": { ... element specification ... }
  }
}
§count: Option<Count>

Optional count specification for the number of elements to generate.

This field determines how many elements will be generated for the array. When not specified (defaults to None), the array will contain exactly one element.

§Default Behavior

The #[serde(default)] attribute ensures that if the count field is omitted from the JGD schema, it defaults to None, which through the GetCount implementation for Option<Count> results in a count of 1.

§Count Types

  • Fixed Count: Some(Count::Fixed(n)) generates exactly n elements
  • Range Count: Some(Count::Range((min, max))) generates between min and max elements
  • Default Count: None generates exactly 1 element

§JSON Schema Mapping

Maps to the optional count property in JGD array specifications:

{
  "array": {
    "of": { ... },
    "count": 5           // Fixed count
  }
}

Or omitted for default behavior:

{
  "array": {
    "of": { ... }
    // count omitted - defaults to 1
  }
}

Trait Implementations§

Source§

impl Clone for ArraySpec

Source§

fn clone(&self) -> ArraySpec

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ArraySpec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ArraySpec

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl JsonGenerator for ArraySpec

Source§

fn generate( &self, config: &mut GeneratorConfig, local_config: Option<&mut LocalConfig>, ) -> Result<Value, JgdGeneratorError>

Generates a JSON array according to the array specification.

This method creates a JSON array by generating the specified number of elements, each conforming to the element specification. The generation process is deterministic when using a seeded generator configuration.

§Generation Process
  1. Count Determination: Uses the count specification to determine array length
  2. Memory Allocation: Pre-allocates a vector with the exact capacity needed
  3. Element Generation: Generates each element independently using the element spec
  4. Array Construction: Constructs and returns a Value::Array containing all elements
§Arguments
  • config - Mutable reference to the generator configuration containing the random number generator, fake data generators, and generation state
§Returns

A serde_json::Value::Array containing the generated elements. The array length will be determined by the count specification, and each element will be generated according to the element specification.

§Count Resolution

The array length is determined by the count specification:

  • Fixed Count: Always generates exactly the specified number
  • Range Count: Randomly selects a count within the range
  • Default (None): Generates exactly 1 element
§Element Independence

Each element is generated independently, which means:

  • Random values will differ between elements (with proper RNG state)
  • Fake data will produce varied realistic values
  • Optional fields may be present or absent independently
  • Cross-references within elements work independently
§Examples
use jgd_rs::{ArraySpec, Field, Count, NumberSpec, JsonGenerator, GeneratorConfig};
use serde_json::{json, Value};

let mut config = GeneratorConfig::new("EN", Some(42));

// Generate array of 3 random integers
let spec = ArraySpec {
    of: Box::new(Field::Number(NumberSpec::new_integer(1.0, 100.0))),
    count: Some(Count::Fixed(3)),
};

let result = spec.generate(&mut config);
match result {
    Value::Array(arr) => {
        assert_eq!(arr.len(), 3);
        for element in arr {
            assert!(element.is_number());
            let num = element.as_i64().unwrap();
            assert!((1..=100).contains(&num));
        }
    }
    _ => panic!("Expected array"),
}
§Performance Notes
  • Memory Efficiency: Pre-allocates vector to avoid reallocations
  • Sequential Generation: Elements are generated in order for predictable results
  • Scalability: Performance scales linearly with array size
  • Memory Usage: Total memory usage is proportional to element count and element size
§Error Handling

This method assumes that:

  • The element specification is valid and can generate values
  • The count specification produces valid non-negative counts
  • The generator configuration is properly initialized

Invalid configurations may result in panics or unexpected behavior.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: Rng + ?Sized, Self: FakeBase<U>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,