use crate::RewritePlan;
use crate::actor::{Envelope, Id};
use crate::util::{HashableHashSet, HashableHashMap};
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::hash::Hash;
use std::sync::Arc;
pub trait Rewrite<R> {
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self;
}
macro_rules! impl_noop_rewrite {
( $( $t:ty ),* ) => {
$(
impl<R> crate::Rewrite<R> for $t {
#[inline(always)]
fn rewrite<S>(&self, _: &RewritePlan<R,S>) -> Self { self.clone() }
}
)*
}
}
impl_noop_rewrite![
(),
bool,
char,
f32, f64,
i8, i16, i32, i64, isize,
&'static str,
u8, u16, u32, u64, usize,
String
];
impl<R, T0, T1> Rewrite<R> for (T0, T1)
where T0: Rewrite<R>,
T1: Rewrite<R>,
{
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
(self.0.rewrite(plan), self.1.rewrite(plan))
}
}
impl<R, T> Rewrite<R> for Arc<T>
where T: Rewrite<R>,
{
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
Arc::new((**self).rewrite(plan))
}
}
impl<R, K, V> Rewrite<R> for BTreeMap<K, V>
where K: Ord + Rewrite<R>,
V: Rewrite<R>,
{
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter()
.map(|(k, v)| (k.rewrite(plan), v.rewrite(plan)))
.collect()
}
}
impl<R, V> Rewrite<R> for BTreeSet<V> where V: Ord + Rewrite<R> {
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter().map(|x| x.rewrite(plan)).collect()
}
}
impl<R, V> Rewrite<R> for HashableHashSet<V> where V: Eq + Hash + Rewrite<R> {
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter().map(|x| x.rewrite(plan)).collect()
}
}
impl<R, K, V> Rewrite<R> for HashableHashMap<K,V>
where V: Eq + Hash + Rewrite<R>,
K: Eq + Hash + Rewrite<R>,
{
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter().map(|(k,v)| (k.rewrite(plan), v.rewrite(plan)) ).collect()
}
}
impl<R, T> Rewrite<R> for Option<T>
where T: Rewrite<R>,
{
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.as_ref().map(|v| v.rewrite(plan))
}
}
impl<R, V> Rewrite<R> for Vec<V> where V: Rewrite<R> {
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter().map(|x| x.rewrite(plan)).collect()
}
}
impl<R, V> Rewrite<R> for VecDeque<V> where V: Rewrite<R> {
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<R,S>) -> Self {
self.iter().map(|x| x.rewrite(plan)).collect()
}
}
impl Rewrite<Id> for Id {
#[inline(always)]
fn rewrite<S>(&self, plan: &RewritePlan<Id,S>) -> Self {
plan.rewrite(self)
}
}
impl<Msg> Rewrite<Id> for Envelope<Msg>
where Msg: Rewrite<Id>,
{
fn rewrite<S>(&self, plan: &RewritePlan<Id,S>) -> Self {
Envelope {
src: self.src.rewrite(plan),
dst: self.dst.rewrite(plan),
msg: self.msg.rewrite(plan),
}
}
}
#[cfg(test)]
mod test {
use crate::{Rewrite, RewritePlan};
use crate::actor::{Envelope, Id, Network};
#[test]
fn can_rewrite_id_vec() {
let original = Id::vec_from(vec![1, 2, 2]);
assert_eq!(
original.rewrite(&RewritePlan::<Id,_>::from_values_to_sort(&vec![2, 0, 1])),
Id::vec_from(vec![0, 1, 1]));
assert_eq!(
original.rewrite(&RewritePlan::<Id,_>::from_values_to_sort(&vec![0, 2, 1])),
Id::vec_from(vec![2, 1, 1]));
}
#[test]
fn can_rewrite_network() {
let original: Network<_> = Network::new_unordered_duplicating([
Envelope { src: 0.into(), dst: 1.into(), msg: "Write(X)" },
Envelope { src: 0.into(), dst: 2.into(), msg: "Write(X)" },
Envelope { src: 1.into(), dst: 0.into(), msg: "Ack(X)" },
Envelope { src: 2.into(), dst: 0.into(), msg: "Ack(X)" },
Envelope { src: 2.into(), dst: 0.into(), msg: "Write(Y)" },
Envelope { src: 2.into(), dst: 1.into(), msg: "Write(Y)" },
Envelope { src: 1.into(), dst: 2.into(), msg: "Ack(Y)" },
]);
assert_eq!(
original.rewrite(&RewritePlan::from_values_to_sort(&vec![2, 0, 1])),
Network::new_unordered_duplicating([
Envelope { src: 2.into(), dst: 0.into(), msg: "Write(X)" },
Envelope { src: 2.into(), dst: 1.into(), msg: "Write(X)" },
Envelope { src: 0.into(), dst: 2.into(), msg: "Ack(X)" },
Envelope { src: 1.into(), dst: 2.into(), msg: "Ack(X)" },
Envelope { src: 1.into(), dst: 2.into(), msg: "Write(Y)" },
Envelope { src: 1.into(), dst: 0.into(), msg: "Write(Y)" },
Envelope { src: 0.into(), dst: 1.into(), msg: "Ack(Y)" },
]));
assert_eq!(
original.rewrite(&RewritePlan::from_values_to_sort(&vec![0, 2, 1])),
Network::new_unordered_duplicating([
Envelope { src: 0.into(), dst: 2.into(), msg: "Write(X)" },
Envelope { src: 0.into(), dst: 1.into(), msg: "Write(X)" },
Envelope { src: 2.into(), dst: 0.into(), msg: "Ack(X)" },
Envelope { src: 1.into(), dst: 0.into(), msg: "Ack(X)" },
Envelope { src: 1.into(), dst: 0.into(), msg: "Write(Y)" },
Envelope { src: 1.into(), dst: 2.into(), msg: "Write(Y)" },
Envelope { src: 2.into(), dst: 1.into(), msg: "Ack(Y)" },
]));
}
}