diff --git a/src/command/config/update.rs b/src/command/config/update.rs index 38342a3..136c2aa 100644 --- a/src/command/config/update.rs +++ b/src/command/config/update.rs @@ -18,24 +18,26 @@ pub(crate) enum UpdateError { RevisionCheck(#[from] RevisionCheckError), #[error(transparent)] FileOperation(#[from] io::Error), + #[error("downgrading is not supported")] + Downgrade, #[error(transparent)] V1(#[from] v1::Error), } pub(super) async fn run(revision: Option) -> Result<(), UpdateError> { - let current_revision = current_revision()?; + let current = current_revision()?; - if current_revision.next().is_none() { + if current.next().is_none() { println!("Your config files are already up-to-date! (as of this fishctl release)"); return Ok(()); } - if current_revision != Revision::V0 { + if current != Revision::V0 { take_backup()?; } match revision { - Some(revision) => update_to(revision).await, - None => update_to_latest_from(current_revision).await, + Some(target) => update(current, target).await, + None => update(current, Revision::last().unwrap()).await, } } @@ -59,17 +61,22 @@ fn take_backup() -> Result<(), UpdateError> { Ok(()) } -async fn update_to_latest_from(mut current_revision: Revision) -> Result<(), UpdateError> { - while let Some(next_revision) = current_revision.next() { - update_to(next_revision.clone()).await?; - current_revision = next_revision; +/// Updates config files to the specified revision. +async fn update(mut current: Revision, target: Revision) -> Result<(), UpdateError> { + if current > target { + return Err(UpdateError::Downgrade); + } + while current < target { + let next = current.next().unwrap(); + update_one_revision(next.clone()).await?; + current = next; } Ok(()) } -/// Updates config files to the specified revision. -async fn update_to(revision: Revision) -> Result<(), UpdateError> { - match revision { +/// Updates config file revision from `target - 1` to `target`. +async fn update_one_revision(target: Revision) -> Result<(), UpdateError> { + match target { Revision::V0 => unreachable!(), Revision::V1 => v1::run().await?, } diff --git a/src/config/mod.rs b/src/config/mod.rs index 3438ff8..743e2c4 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -11,7 +11,9 @@ use validator::ValidationError; pub(crate) const SERVER_CONFIG_PATH: &str = "config/server.toml"; pub(crate) const CLIENT_CONFIG_PATH: &str = "config/client.toml"; -#[derive(Deserialize_repr, Serialize_repr, PartialEq, Clone, ValueEnum, Sequence, Debug)] +#[derive( + Deserialize_repr, Serialize_repr, PartialEq, PartialOrd, Clone, ValueEnum, Sequence, Debug, +)] #[clap(rename_all = "lowercase")] #[repr(u8)] pub enum Revision {