pub struct Migrator { /* private fields */ }Expand description
The migration manager that orchestrates all migrations.
Implementations§
Source§impl Migrator
impl Migrator
Sourcepub fn get_latest_version(&self, entity: &str) -> Option<&str>
pub fn get_latest_version(&self, entity: &str) -> Option<&str>
Gets the latest version for a given entity.
§Returns
The latest version string if the entity is registered, None otherwise.
Sourcepub fn define(entity: &str) -> MigrationPathBuilder<Start>
pub fn define(entity: &str) -> MigrationPathBuilder<Start>
Starts defining a migration path for an entity.
Sourcepub fn register<D>(
&mut self,
path: MigrationPath<D>,
) -> Result<(), MigrationError>
pub fn register<D>( &mut self, path: MigrationPath<D>, ) -> Result<(), MigrationError>
Registers a migration path with validation.
This method validates the migration path before registering it:
- Checks for circular migration paths
- Validates version ordering follows semver rules
§Errors
Returns an error if validation fails.
Sourcepub fn load_from<D, T>(
&self,
entity: &str,
data: T,
) -> Result<D, MigrationError>where
D: DeserializeOwned,
T: Serialize,
pub fn load_from<D, T>(
&self,
entity: &str,
data: T,
) -> Result<D, MigrationError>where
D: DeserializeOwned,
T: Serialize,
Loads and migrates data from any serde-compatible format.
This is the generic version that accepts any type implementing Serialize.
For JSON strings, use the convenience method load instead.
§Arguments
entity- The entity name used when registering the migration pathdata- Versioned data in any serde-compatible format (e.g.,toml::Value,serde_json::Value)
§Returns
The migrated data as the domain model type
§Errors
Returns an error if:
- The data cannot be converted to the internal format
- The entity is not registered
- A migration step fails
§Example
// Load from TOML
let toml_data: toml::Value = toml::from_str(toml_str)?;
let domain: TaskEntity = migrator.load_from("task", toml_data)?;
// Load from JSON Value
let json_data: serde_json::Value = serde_json::from_str(json_str)?;
let domain: TaskEntity = migrator.load_from("task", json_data)?;Sourcepub fn load<D: DeserializeOwned>(
&self,
entity: &str,
json: &str,
) -> Result<D, MigrationError>
pub fn load<D: DeserializeOwned>( &self, entity: &str, json: &str, ) -> Result<D, MigrationError>
Loads and migrates data from a JSON string.
This is a convenience method for the common case of loading from JSON.
For other formats, use load_from instead.
§Arguments
entity- The entity name used when registering the migration pathjson- A JSON string containing versioned data
§Returns
The migrated data as the domain model type
§Errors
Returns an error if:
- The JSON cannot be parsed
- The entity is not registered
- A migration step fails
§Example
let json = r#"{"version":"1.0.0","data":{"id":"task-1","title":"My Task"}}"#;
let domain: TaskEntity = migrator.load("task", json)?;Sourcepub fn load_flat<D: DeserializeOwned>(
&self,
entity: &str,
json: &str,
) -> Result<D, MigrationError>
pub fn load_flat<D: DeserializeOwned>( &self, entity: &str, json: &str, ) -> Result<D, MigrationError>
Loads and migrates data from a flat format JSON string.
This is a convenience method for loading from flat format JSON where the version field is at the same level as the data fields.
§Arguments
entity- The entity name used when registering the migration pathjson- A JSON string containing versioned data in flat format
§Returns
The migrated data as the domain model type
§Errors
Returns an error if:
- The JSON cannot be parsed
- The entity is not registered
- A migration step fails
§Example
let json = r#"{"version":"1.0.0","id":"task-1","title":"My Task"}"#;
let domain: TaskEntity = migrator.load_flat("task", json)?;Sourcepub fn load_flat_from<D, T>(
&self,
entity: &str,
value: T,
) -> Result<D, MigrationError>where
D: DeserializeOwned,
T: Serialize,
pub fn load_flat_from<D, T>(
&self,
entity: &str,
value: T,
) -> Result<D, MigrationError>where
D: DeserializeOwned,
T: Serialize,
Loads and migrates data from any serde-compatible format in flat format.
This method expects the version field to be at the same level as the data fields. It uses the registered migration path’s runtime-configured keys (respecting the Path > Migrator > Trait priority).
§Arguments
entity- The entity name used when registering the migration pathvalue- A serde-compatible value containing versioned data in flat format
§Returns
The migrated data as the domain model type
§Errors
Returns an error if:
- The entity is not registered
- The data format is invalid
- A migration step fails
§Example
let toml_value: toml::Value = toml::from_str(toml_str)?;
let domain: TaskEntity = migrator.load_flat_from("task", toml_value)?;Sourcepub fn save<T: Versioned + Serialize>(
&self,
data: T,
) -> Result<String, MigrationError>
pub fn save<T: Versioned + Serialize>( &self, data: T, ) -> Result<String, MigrationError>
Saves versioned data to a JSON string.
This method wraps the provided data with its version information and serializes
it to JSON format. The resulting JSON can later be loaded and migrated using
the load method.
§Arguments
data- The versioned data to save
§Returns
A JSON string with the format: {"version":"x.y.z","data":{...}}
§Errors
Returns SerializationError if the data cannot be serialized to JSON.
§Example
let task = TaskV1_0_0 {
id: "task-1".to_string(),
title: "My Task".to_string(),
};
let migrator = Migrator::new();
let json = migrator.save(task)?;
// json: {"version":"1.0.0","data":{"id":"task-1","title":"My Task"}}Sourcepub fn save_flat<T: Versioned + Serialize>(
&self,
data: T,
) -> Result<String, MigrationError>
pub fn save_flat<T: Versioned + Serialize>( &self, data: T, ) -> Result<String, MigrationError>
Saves versioned data to a JSON string in flat format.
Unlike save(), this method produces a flat JSON structure where the version
field is at the same level as the data fields, not wrapped in a separate object.
§Arguments
data- The versioned data to save
§Returns
A JSON string with the format: {"version":"x.y.z","field1":"value1",...}
§Errors
Returns SerializationError if the data cannot be serialized to JSON.
§Example
let task = TaskV1_0_0 {
id: "task-1".to_string(),
title: "My Task".to_string(),
};
let migrator = Migrator::new();
let json = migrator.save_flat(task)?;
// json: {"version":"1.0.0","id":"task-1","title":"My Task"}Sourcepub fn load_vec_from<D, T>(
&self,
entity: &str,
data: Vec<T>,
) -> Result<Vec<D>, MigrationError>where
D: DeserializeOwned,
T: Serialize,
pub fn load_vec_from<D, T>(
&self,
entity: &str,
data: Vec<T>,
) -> Result<Vec<D>, MigrationError>where
D: DeserializeOwned,
T: Serialize,
Loads and migrates multiple entities from any serde-compatible format.
This is the generic version that accepts any type implementing Serialize.
For JSON arrays, use the convenience method load_vec instead.
§Arguments
entity- The entity name used when registering the migration pathdata- Array of versioned data in any serde-compatible format
§Returns
A vector of migrated data as domain model types
§Errors
Returns an error if:
- The data cannot be converted to the internal format
- The entity is not registered
- Any migration step fails
§Example
// Load from TOML array
let toml_array: Vec<toml::Value> = /* ... */;
let domains: Vec<TaskEntity> = migrator.load_vec_from("task", toml_array)?;
// Load from JSON Value array
let json_array: Vec<serde_json::Value> = /* ... */;
let domains: Vec<TaskEntity> = migrator.load_vec_from("task", json_array)?;Sourcepub fn load_vec<D: DeserializeOwned>(
&self,
entity: &str,
json: &str,
) -> Result<Vec<D>, MigrationError>
pub fn load_vec<D: DeserializeOwned>( &self, entity: &str, json: &str, ) -> Result<Vec<D>, MigrationError>
Loads and migrates multiple entities from a JSON array string.
This is a convenience method for the common case of loading from a JSON array.
For other formats, use load_vec_from instead.
§Arguments
entity- The entity name used when registering the migration pathjson- A JSON array string containing versioned data
§Returns
A vector of migrated data as domain model types
§Errors
Returns an error if:
- The JSON cannot be parsed
- The entity is not registered
- Any migration step fails
§Example
let json = r#"[
{"version":"1.0.0","data":{"id":"task-1","title":"Task 1"}},
{"version":"1.0.0","data":{"id":"task-2","title":"Task 2"}}
]"#;
let domains: Vec<TaskEntity> = migrator.load_vec("task", json)?;Sourcepub fn load_vec_flat<D: DeserializeOwned>(
&self,
entity: &str,
json: &str,
) -> Result<Vec<D>, MigrationError>
pub fn load_vec_flat<D: DeserializeOwned>( &self, entity: &str, json: &str, ) -> Result<Vec<D>, MigrationError>
Loads and migrates multiple entities from a flat format JSON array string.
This is a convenience method for loading from a JSON array where each element has the version field at the same level as the data fields.
§Arguments
entity- The entity name used when registering the migration pathjson- A JSON array string containing versioned data in flat format
§Returns
A vector of migrated data as domain model types
§Errors
Returns an error if:
- The JSON cannot be parsed
- The entity is not registered
- Any migration step fails
§Example
let json = r#"[
{"version":"1.0.0","id":"task-1","title":"Task 1"},
{"version":"1.0.0","id":"task-2","title":"Task 2"}
]"#;
let domains: Vec<TaskEntity> = migrator.load_vec_flat("task", json)?;Sourcepub fn load_vec_flat_from<D, T>(
&self,
entity: &str,
data: Vec<T>,
) -> Result<Vec<D>, MigrationError>where
D: DeserializeOwned,
T: Serialize,
pub fn load_vec_flat_from<D, T>(
&self,
entity: &str,
data: Vec<T>,
) -> Result<Vec<D>, MigrationError>where
D: DeserializeOwned,
T: Serialize,
Loads and migrates multiple entities from any serde-compatible format in flat format.
This method expects each element to have the version field at the same level as the data fields. It uses the registered migration path’s runtime-configured keys (respecting the Path > Migrator > Trait priority).
§Arguments
entity- The entity name used when registering the migration pathdata- Vector of serde-compatible values in flat format
§Returns
A vector of migrated data as domain model types
§Errors
Returns an error if:
- The entity is not registered
- The data format is invalid
- Any migration step fails
§Example
let toml_array: Vec<toml::Value> = /* ... */;
let domains: Vec<TaskEntity> = migrator.load_vec_flat_from("task", toml_array)?;Sourcepub fn save_vec<T: Versioned + Serialize>(
&self,
data: Vec<T>,
) -> Result<String, MigrationError>
pub fn save_vec<T: Versioned + Serialize>( &self, data: Vec<T>, ) -> Result<String, MigrationError>
Saves multiple versioned entities to a JSON array string.
This method wraps each item with its version information and serializes
them as a JSON array. The resulting JSON can later be loaded and migrated
using the load_vec method.
§Arguments
data- Vector of versioned data to save
§Returns
A JSON array string where each element has the format: {"version":"x.y.z","data":{...}}
§Errors
Returns SerializationError if the data cannot be serialized to JSON.
§Example
let tasks = vec![
TaskV1_0_0 {
id: "task-1".to_string(),
title: "Task 1".to_string(),
},
TaskV1_0_0 {
id: "task-2".to_string(),
title: "Task 2".to_string(),
},
];
let migrator = Migrator::new();
let json = migrator.save_vec(tasks)?;
// json: [{"version":"1.0.0","data":{"id":"task-1",...}}, ...]Sourcepub fn save_vec_flat<T: Versioned + Serialize>(
&self,
data: Vec<T>,
) -> Result<String, MigrationError>
pub fn save_vec_flat<T: Versioned + Serialize>( &self, data: Vec<T>, ) -> Result<String, MigrationError>
Saves multiple versioned entities to a JSON array string in flat format.
This method serializes each item with the version field at the same level as the data fields, not wrapped in a separate object.
§Arguments
data- Vector of versioned data to save
§Returns
A JSON array string where each element has the format: {"version":"x.y.z","field1":"value1",...}
§Errors
Returns SerializationError if the data cannot be serialized to JSON.
§Example
let tasks = vec![
TaskV1_0_0 {
id: "task-1".to_string(),
title: "Task 1".to_string(),
},
TaskV1_0_0 {
id: "task-2".to_string(),
title: "Task 2".to_string(),
},
];
let migrator = Migrator::new();
let json = migrator.save_vec_flat(tasks)?;
// json: [{"version":"1.0.0","id":"task-1",...}, ...]Sourcepub fn save_entity<E: LatestVersioned>(
&self,
entity: E,
) -> Result<String, MigrationError>
pub fn save_entity<E: LatestVersioned>( &self, entity: E, ) -> Result<String, MigrationError>
Saves a domain entity to a JSON string using its latest versioned format.
This method automatically converts the domain entity to its latest version and saves it with version information.
§Arguments
entity- The domain entity to save (must implementLatestVersioned)
§Returns
A JSON string with the format: {"version":"x.y.z","data":{...}}
§Errors
Returns SerializationError if the entity cannot be serialized to JSON.
§Example
#[version_migrate(entity = "task", latest = TaskV1_1_0)]
struct TaskEntity {
id: String,
title: String,
description: Option<String>,
}
let entity = TaskEntity {
id: "task-1".to_string(),
title: "My Task".to_string(),
description: Some("Description".to_string()),
};
let migrator = Migrator::new();
let json = migrator.save_entity(entity)?;
// Automatically saved with latest version (1.1.0)Sourcepub fn save_entity_flat<E: LatestVersioned>(
&self,
entity: E,
) -> Result<String, MigrationError>
pub fn save_entity_flat<E: LatestVersioned>( &self, entity: E, ) -> Result<String, MigrationError>
Saves a domain entity to a JSON string in flat format using its latest versioned format.
This method automatically converts the domain entity to its latest version and saves it with the version field at the same level as data fields.
§Arguments
entity- The domain entity to save (must implementLatestVersioned)
§Returns
A JSON string with the format: {"version":"x.y.z","field1":"value1",...}
§Errors
Returns SerializationError if the entity cannot be serialized to JSON.
§Example
#[version_migrate(entity = "task", latest = TaskV1_1_0)]
struct TaskEntity {
id: String,
title: String,
description: Option<String>,
}
let entity = TaskEntity {
id: "task-1".to_string(),
title: "My Task".to_string(),
description: Some("Description".to_string()),
};
let migrator = Migrator::new();
let json = migrator.save_entity_flat(entity)?;
// json: {"version":"1.1.0","id":"task-1","title":"My Task",...}Sourcepub fn save_entity_vec<E: LatestVersioned>(
&self,
entities: Vec<E>,
) -> Result<String, MigrationError>
pub fn save_entity_vec<E: LatestVersioned>( &self, entities: Vec<E>, ) -> Result<String, MigrationError>
Saves multiple domain entities to a JSON array string using their latest versioned format.
This method automatically converts each domain entity to its latest version and saves them as a JSON array.
§Arguments
entities- Vector of domain entities to save
§Returns
A JSON array string where each element has the format: {"version":"x.y.z","data":{...}}
§Errors
Returns SerializationError if the entities cannot be serialized to JSON.
§Example
let entities = vec![
TaskEntity { id: "1".into(), title: "Task 1".into(), description: None },
TaskEntity { id: "2".into(), title: "Task 2".into(), description: None },
];
let json = migrator.save_entity_vec(entities)?;Sourcepub fn save_entity_vec_flat<E: LatestVersioned>(
&self,
entities: Vec<E>,
) -> Result<String, MigrationError>
pub fn save_entity_vec_flat<E: LatestVersioned>( &self, entities: Vec<E>, ) -> Result<String, MigrationError>
Saves multiple domain entities to a JSON array string in flat format using their latest versioned format.
This method automatically converts each domain entity to its latest version and saves them with version fields at the same level as data fields.
§Arguments
entities- Vector of domain entities to save
§Returns
A JSON array string where each element has the format: {"version":"x.y.z","field1":"value1",...}
§Errors
Returns SerializationError if the entities cannot be serialized to JSON.
§Example
let entities = vec![
TaskEntity { id: "1".into(), title: "Task 1".into(), description: None },
TaskEntity { id: "2".into(), title: "Task 2".into(), description: None },
];
let json = migrator.save_entity_vec_flat(entities)?;Sourcepub fn save_domain<T: Serialize>(
&self,
entity_name: &str,
entity: T,
) -> Result<String, MigrationError>
pub fn save_domain<T: Serialize>( &self, entity_name: &str, entity: T, ) -> Result<String, MigrationError>
Saves a domain entity to a JSON string using its latest versioned format, by entity name.
This method works without requiring the VersionMigrate macro on the entity type.
Instead, it uses the save function registered during register() via into_with_save().
§Arguments
entity_name- The entity name used when registering the migration pathentity- The domain entity to save (must be Serialize)
§Returns
A JSON string with the format: {"version":"x.y.z","data":{...}}
§Errors
Returns MigrationPathNotDefined if the entity is not registered with save support.
Returns SerializationError if the entity cannot be serialized.
§Example
impl FromDomain<TaskEntity> for TaskV1_1_0 {
fn from_domain(entity: TaskEntity) -> Self { ... }
}
let path = Migrator::define("task")
.from::<TaskV1_0_0>()
.step::<TaskV1_1_0>()
.into_with_save::<TaskEntity>();
migrator.register(path)?;
let entity = TaskEntity { ... };
let json = migrator.save_domain("task", entity)?;
// → {"version":"1.1.0","data":{"id":"1","title":"My Task",...}}Sourcepub fn save_domain_flat<T: Serialize>(
&self,
entity_name: &str,
entity: T,
) -> Result<String, MigrationError>
pub fn save_domain_flat<T: Serialize>( &self, entity_name: &str, entity: T, ) -> Result<String, MigrationError>
Saves a domain entity to a JSON string in flat format using its latest versioned format, by entity name.
This method works without requiring the VersionMigrate macro on the entity type.
The version field is placed at the same level as data fields.
§Arguments
entity_name- The entity name used when registering the migration pathentity- The domain entity to save (must be Serialize)
§Returns
A JSON string with the format: {"version":"x.y.z","field1":"value1",...}
§Errors
Returns MigrationPathNotDefined if the entity is not registered with save support.
Returns SerializationError if the entity cannot be serialized.
§Example
let json = migrator.save_domain_flat("task", entity)?;
// → {"version":"1.1.0","id":"1","title":"My Task",...}