use rpstate::store::builder::StoreBuilder;
use rpstate::{Store, migrate};
use rpstate_macros::rpstate;
use std::sync::Arc;
mod v1 {
use super::*;
#[rpstate(prefix = "app", version = 1)]
pub struct Config {
#[state(default = "localhost".to_string())]
pub host: String,
}
}
#[rpstate(prefix = "app", version = 2)]
pub struct Config {
#[state(default = "localhost".to_string())]
pub address: String,
#[state(default = 8080)]
pub port: u16,
}
migrate! {
v1::Config_Data => Config_Data,
rename: [host => address],
|old| {
Ok(Self {
address: old.host,
port: 9090,
})
}
}
#[cfg(feature = "redb")]
#[test]
fn test_decentralized_codegen_migration() {
let path = std::env::temp_dir().join("rpstate_integration_test.redb");
if path.exists() {
std::fs::remove_file(&path).ok();
}
{
let store = Arc::new(StoreBuilder::new(&path).build().unwrap());
let config = v1::Config::new(&store).unwrap();
config.host().set("10.0.0.1".to_string()).unwrap();
}
let (store, _) = StoreBuilder::new(&path)
.collect_migrations()
.build()
.unwrap();
let config = Config::new(&store).expect("Failed to create Config");
assert_eq!(config.address().get(), "10.0.0.1");
assert_eq!(config.port().get(), 9090);
let old_val: Option<String> = store.get("app.host").unwrap();
assert!(
old_val.is_none(),
"Old key 'app.host' should be deleted after migration"
);
let new_val: Option<String> = store.get("app.address").unwrap();
assert_eq!(new_val, Some("10.0.0.1".to_string()));
}