-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor: move
rewrite
inside hugr
, Rewrite
-> Replace
implem…
…enting new 'Rewrite' trait (#119) * Remove Pattern and Pattern.rs * Move rewrite module to hugr/rewrite * Rename old `Rewrite` struct to `Replace` but leave as skeletal * Add `Rewrite` trait, (parameterized) Hugr::apply_rewrite dispatches to that * Associated `Error` type and `unchanged_on_failure: bool` * unchanged_on_failure as trait associated constant * Drive-by: simple_replace.rs: change ".ok();"s to unwrap
- Loading branch information
Showing
7 changed files
with
295 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
//! Rewrite operations on the HUGR - replacement, outlining, etc. | ||
|
||
pub mod replace; | ||
pub mod simple_replace; | ||
use std::mem; | ||
|
||
use crate::Hugr; | ||
pub use replace::{OpenHugr, Replace, ReplaceError}; | ||
pub use simple_replace::{SimpleReplacement, SimpleReplacementError}; | ||
|
||
/// An operation that can be applied to mutate a Hugr | ||
pub trait Rewrite { | ||
/// The type of Error with which this Rewrite may fail | ||
type Error: std::error::Error; | ||
|
||
/// If `true`, [self.apply]'s of this rewrite guarantee that they do not mutate the Hugr when they return an Err. | ||
/// If `false`, there is no guarantee; the Hugr should be assumed invalid when Err is returned. | ||
const UNCHANGED_ON_FAILURE: bool; | ||
|
||
/// Checks whether the rewrite would succeed on the specified Hugr. | ||
/// If this call succeeds, [self.apply] should also succeed on the same `h` | ||
/// If this calls fails, [self.apply] would fail with the same error. | ||
fn verify(&self, h: &Hugr) -> Result<(), Self::Error>; | ||
|
||
/// Mutate the specified Hugr, or fail with an error. | ||
/// If [self.unchanged_on_failure] is true, then `h` must be unchanged if Err is returned. | ||
/// See also [self.verify] | ||
/// # Panics | ||
/// May panic if-and-only-if `h` would have failed [Hugr::validate]; that is, | ||
/// implementations may begin with `assert!(h.validate())`, with `debug_assert!(h.validate())` | ||
/// being preferred. | ||
fn apply(self, h: &mut Hugr) -> Result<(), Self::Error>; | ||
} | ||
|
||
/// Wraps any rewrite into a transaction (i.e. that has no effect upon failure) | ||
pub struct Transactional<R> { | ||
underlying: R, | ||
} | ||
|
||
// Note we might like to constrain R to Rewrite<unchanged_on_failure=false> but this | ||
// is not yet supported, https://github.com/rust-lang/rust/issues/92827 | ||
impl<R: Rewrite> Rewrite for Transactional<R> { | ||
type Error = R::Error; | ||
const UNCHANGED_ON_FAILURE: bool = true; | ||
|
||
fn verify(&self, h: &Hugr) -> Result<(), Self::Error> { | ||
self.underlying.verify(h) | ||
} | ||
|
||
fn apply(self, h: &mut Hugr) -> Result<(), Self::Error> { | ||
if R::UNCHANGED_ON_FAILURE { | ||
return self.underlying.apply(h); | ||
} | ||
let backup = h.clone(); | ||
let r = self.underlying.apply(h); | ||
if r.is_err() { | ||
// drop the old h, it was undefined | ||
let _ = mem::replace(h, backup); | ||
} | ||
r | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.