remove old stuff
This commit is contained in:
parent
aca79bd728
commit
db79468435
|
@ -1,430 +0,0 @@
|
||||||
use indexmap::IndexSet;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use uplc::builtins::DefaultFunction;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ast::{BinOp, UnOp},
|
|
||||||
tipo::{Type, ValueConstructor},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::scope::Scope;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum Air {
|
|
||||||
// Primitives
|
|
||||||
Int {
|
|
||||||
scope: Scope,
|
|
||||||
value: String,
|
|
||||||
},
|
|
||||||
String {
|
|
||||||
scope: Scope,
|
|
||||||
value: String,
|
|
||||||
},
|
|
||||||
ByteArray {
|
|
||||||
scope: Scope,
|
|
||||||
bytes: Vec<u8>,
|
|
||||||
},
|
|
||||||
Bool {
|
|
||||||
scope: Scope,
|
|
||||||
value: bool,
|
|
||||||
},
|
|
||||||
List {
|
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail: bool,
|
|
||||||
},
|
|
||||||
Tuple {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
Void {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
Var {
|
|
||||||
scope: Scope,
|
|
||||||
constructor: ValueConstructor,
|
|
||||||
name: String,
|
|
||||||
variant_name: String,
|
|
||||||
},
|
|
||||||
// Functions
|
|
||||||
Call {
|
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
DefineFunc {
|
|
||||||
scope: Scope,
|
|
||||||
func_name: String,
|
|
||||||
module_name: String,
|
|
||||||
params: Vec<String>,
|
|
||||||
recursive: bool,
|
|
||||||
variant_name: String,
|
|
||||||
},
|
|
||||||
Fn {
|
|
||||||
scope: Scope,
|
|
||||||
params: Vec<String>,
|
|
||||||
},
|
|
||||||
Builtin {
|
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
|
||||||
func: DefaultFunction,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Operators
|
|
||||||
BinOp {
|
|
||||||
scope: Scope,
|
|
||||||
name: BinOp,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
UnOp {
|
|
||||||
scope: Scope,
|
|
||||||
op: UnOp,
|
|
||||||
},
|
|
||||||
// Assignment
|
|
||||||
Let {
|
|
||||||
scope: Scope,
|
|
||||||
name: String,
|
|
||||||
},
|
|
||||||
UnWrapData {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
WrapData {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
AssertConstr {
|
|
||||||
scope: Scope,
|
|
||||||
constr_index: usize,
|
|
||||||
},
|
|
||||||
AssertBool {
|
|
||||||
scope: Scope,
|
|
||||||
is_true: bool,
|
|
||||||
},
|
|
||||||
// When
|
|
||||||
When {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
subject_name: String,
|
|
||||||
},
|
|
||||||
Clause {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
subject_name: String,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
ListClause {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
|
||||||
next_tail_name: Option<String>,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
WrapClause {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
TupleClause {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
indices: IndexSet<(usize, String)>,
|
|
||||||
predefined_indices: IndexSet<(usize, String)>,
|
|
||||||
subject_name: String,
|
|
||||||
count: usize,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
ClauseGuard {
|
|
||||||
scope: Scope,
|
|
||||||
subject_name: String,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
ListClauseGuard {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
|
||||||
next_tail_name: Option<String>,
|
|
||||||
inverse: bool,
|
|
||||||
},
|
|
||||||
Finally {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
// If
|
|
||||||
If {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Record Creation
|
|
||||||
Record {
|
|
||||||
scope: Scope,
|
|
||||||
tag: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
RecordUpdate {
|
|
||||||
scope: Scope,
|
|
||||||
highest_index: usize,
|
|
||||||
indices: Vec<(usize, Arc<Type>)>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Field Access
|
|
||||||
RecordAccess {
|
|
||||||
scope: Scope,
|
|
||||||
record_index: u64,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
FieldsExpose {
|
|
||||||
scope: Scope,
|
|
||||||
indices: Vec<(usize, String, Arc<Type>)>,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
// ListAccess
|
|
||||||
ListAccessor {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
names: Vec<String>,
|
|
||||||
tail: bool,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
ListExpose {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_head_names: Vec<(String, String)>,
|
|
||||||
tail: Option<(String, String)>,
|
|
||||||
},
|
|
||||||
// Tuple Access
|
|
||||||
TupleAccessor {
|
|
||||||
scope: Scope,
|
|
||||||
names: Vec<String>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
TupleIndex {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tuple_index: usize,
|
|
||||||
},
|
|
||||||
// Misc.
|
|
||||||
ErrorTerm {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
Trace {
|
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
NoOp {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
FieldsEmpty {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
ListEmpty {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Air {
|
|
||||||
pub fn scope(&self) -> Scope {
|
|
||||||
match self {
|
|
||||||
Air::Int { scope, .. }
|
|
||||||
| Air::String { scope, .. }
|
|
||||||
| Air::ByteArray { scope, .. }
|
|
||||||
| Air::Bool { scope, .. }
|
|
||||||
| Air::List { scope, .. }
|
|
||||||
| Air::Tuple { scope, .. }
|
|
||||||
| Air::Void { scope }
|
|
||||||
| Air::Var { scope, .. }
|
|
||||||
| Air::Call { scope, .. }
|
|
||||||
| Air::DefineFunc { scope, .. }
|
|
||||||
| Air::Fn { scope, .. }
|
|
||||||
| Air::Builtin { scope, .. }
|
|
||||||
| Air::BinOp { scope, .. }
|
|
||||||
| Air::UnOp { scope, .. }
|
|
||||||
| Air::Let { scope, .. }
|
|
||||||
| Air::UnWrapData { scope, .. }
|
|
||||||
| Air::WrapData { scope, .. }
|
|
||||||
| Air::AssertConstr { scope, .. }
|
|
||||||
| Air::AssertBool { scope, .. }
|
|
||||||
| Air::When { scope, .. }
|
|
||||||
| Air::Clause { scope, .. }
|
|
||||||
| Air::ListClause { scope, .. }
|
|
||||||
| Air::WrapClause { scope }
|
|
||||||
| Air::TupleClause { scope, .. }
|
|
||||||
| Air::ClauseGuard { scope, .. }
|
|
||||||
| Air::ListClauseGuard { scope, .. }
|
|
||||||
| Air::Finally { scope }
|
|
||||||
| Air::If { scope, .. }
|
|
||||||
| Air::Record { scope, .. }
|
|
||||||
| Air::RecordUpdate { scope, .. }
|
|
||||||
| Air::RecordAccess { scope, .. }
|
|
||||||
| Air::FieldsExpose { scope, .. }
|
|
||||||
| Air::FieldsEmpty { scope }
|
|
||||||
| Air::ListEmpty { scope }
|
|
||||||
| Air::ListAccessor { scope, .. }
|
|
||||||
| Air::ListExpose { scope, .. }
|
|
||||||
| Air::TupleAccessor { scope, .. }
|
|
||||||
| Air::TupleIndex { scope, .. }
|
|
||||||
| Air::ErrorTerm { scope, .. }
|
|
||||||
| Air::Trace { scope, .. }
|
|
||||||
| Air::NoOp { scope, .. } => scope.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn scope_mut(&mut self) -> &mut Scope {
|
|
||||||
match self {
|
|
||||||
Air::Int { scope, .. }
|
|
||||||
| Air::String { scope, .. }
|
|
||||||
| Air::ByteArray { scope, .. }
|
|
||||||
| Air::Bool { scope, .. }
|
|
||||||
| Air::List { scope, .. }
|
|
||||||
| Air::Tuple { scope, .. }
|
|
||||||
| Air::Void { scope }
|
|
||||||
| Air::Var { scope, .. }
|
|
||||||
| Air::Call { scope, .. }
|
|
||||||
| Air::DefineFunc { scope, .. }
|
|
||||||
| Air::Fn { scope, .. }
|
|
||||||
| Air::Builtin { scope, .. }
|
|
||||||
| Air::BinOp { scope, .. }
|
|
||||||
| Air::UnOp { scope, .. }
|
|
||||||
| Air::Let { scope, .. }
|
|
||||||
| Air::UnWrapData { scope, .. }
|
|
||||||
| Air::WrapData { scope, .. }
|
|
||||||
| Air::AssertConstr { scope, .. }
|
|
||||||
| Air::AssertBool { scope, .. }
|
|
||||||
| Air::When { scope, .. }
|
|
||||||
| Air::Clause { scope, .. }
|
|
||||||
| Air::ListClause { scope, .. }
|
|
||||||
| Air::WrapClause { scope }
|
|
||||||
| Air::TupleClause { scope, .. }
|
|
||||||
| Air::ClauseGuard { scope, .. }
|
|
||||||
| Air::ListClauseGuard { scope, .. }
|
|
||||||
| Air::Finally { scope }
|
|
||||||
| Air::If { scope, .. }
|
|
||||||
| Air::Record { scope, .. }
|
|
||||||
| Air::RecordUpdate { scope, .. }
|
|
||||||
| Air::RecordAccess { scope, .. }
|
|
||||||
| Air::FieldsExpose { scope, .. }
|
|
||||||
| Air::FieldsEmpty { scope }
|
|
||||||
| Air::ListEmpty { scope }
|
|
||||||
| Air::ListAccessor { scope, .. }
|
|
||||||
| Air::ListExpose { scope, .. }
|
|
||||||
| Air::TupleAccessor { scope, .. }
|
|
||||||
| Air::TupleIndex { scope, .. }
|
|
||||||
| Air::ErrorTerm { scope, .. }
|
|
||||||
| Air::Trace { scope, .. }
|
|
||||||
| Air::NoOp { scope, .. } => scope,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn tipo(&self) -> Option<Arc<Type>> {
|
|
||||||
match self {
|
|
||||||
Air::Int { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Int".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::String { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "String".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::ByteArray { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "ByteArray".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Bool { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Bool".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Void { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Void".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::WrapData { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Data".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Var { constructor, .. } => Some(constructor.tipo.clone()),
|
|
||||||
Air::List { tipo, .. }
|
|
||||||
| Air::Tuple { tipo, .. }
|
|
||||||
| Air::Call { tipo, .. }
|
|
||||||
| Air::Builtin { tipo, .. }
|
|
||||||
| Air::BinOp { tipo, .. }
|
|
||||||
| Air::UnWrapData { tipo, .. }
|
|
||||||
| Air::When { tipo, .. }
|
|
||||||
| Air::Clause { tipo, .. }
|
|
||||||
| Air::ListClause { tipo, .. }
|
|
||||||
| Air::TupleClause { tipo, .. }
|
|
||||||
| Air::ClauseGuard { tipo, .. }
|
|
||||||
| Air::If { tipo, .. }
|
|
||||||
| Air::ListClauseGuard { tipo, .. }
|
|
||||||
| Air::Record { tipo, .. }
|
|
||||||
| Air::RecordUpdate { tipo, .. }
|
|
||||||
| Air::RecordAccess { tipo, .. }
|
|
||||||
| Air::ListAccessor { tipo, .. }
|
|
||||||
| Air::ListExpose { tipo, .. }
|
|
||||||
| Air::TupleAccessor { tipo, .. }
|
|
||||||
| Air::TupleIndex { tipo, .. }
|
|
||||||
| Air::ErrorTerm { tipo, .. }
|
|
||||||
| Air::Trace { tipo, .. } => Some(tipo.clone()),
|
|
||||||
Air::DefineFunc { .. }
|
|
||||||
| Air::Fn { .. }
|
|
||||||
| Air::Let { .. }
|
|
||||||
| Air::WrapClause { .. }
|
|
||||||
| Air::AssertConstr { .. }
|
|
||||||
| Air::AssertBool { .. }
|
|
||||||
| Air::Finally { .. }
|
|
||||||
| Air::FieldsExpose { .. }
|
|
||||||
| Air::FieldsEmpty { .. }
|
|
||||||
| Air::ListEmpty { .. }
|
|
||||||
| Air::NoOp { .. } => None,
|
|
||||||
Air::UnOp { op, .. } => match op {
|
|
||||||
UnOp::Not => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Bool".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
UnOp::Negate => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Int".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
|
||||||
pub struct Scope(pub(self) Vec<u64>);
|
|
||||||
|
|
||||||
impl From<Vec<u64>> for Scope {
|
|
||||||
fn from(value: Vec<u64>) -> Self {
|
|
||||||
Self(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scope {
|
|
||||||
pub fn push(&mut self, value: u64) {
|
|
||||||
self.0.push(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the common ancestor with the replacement,
|
|
||||||
/// remove it from `self`, and then prepend the
|
|
||||||
/// `replacement` to `self`.
|
|
||||||
pub fn replace(&mut self, mut replacement: Scope) {
|
|
||||||
let common = self.common_ancestor(&replacement);
|
|
||||||
|
|
||||||
// we know that common will always be in the front of the
|
|
||||||
// scope Vec so we can always drain `0..common.len()`.
|
|
||||||
self.0.drain(0..common.0.len());
|
|
||||||
|
|
||||||
replacement.0.extend(self.0.iter());
|
|
||||||
self.0 = replacement.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn common_ancestor(&self, other: &Self) -> Scope {
|
|
||||||
let longest_length = self.0.len().max(other.0.len());
|
|
||||||
|
|
||||||
if *self.0 == *other.0 {
|
|
||||||
return self.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
for index in 0..longest_length {
|
|
||||||
if self.0.get(index).is_none() {
|
|
||||||
return self.clone();
|
|
||||||
} else if other.0.get(index).is_none() {
|
|
||||||
return other.clone();
|
|
||||||
} else if self.0[index] != other.0[index] {
|
|
||||||
return Scope(self.0[0..index].to_vec());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use super::Scope;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn common_ancestor_equal_vecs() {
|
|
||||||
let ancestor = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let descendant = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let result = ancestor.common_ancestor(&descendant);
|
|
||||||
|
|
||||||
assert_eq!(result, Scope(vec![1, 2, 3, 4, 5, 6]))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn common_ancestor_equal_ancestor() {
|
|
||||||
let ancestor = Scope(vec![1, 2, 3, 4]);
|
|
||||||
|
|
||||||
let descendant = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let result = ancestor.common_ancestor(&descendant);
|
|
||||||
|
|
||||||
assert_eq!(result, Scope(vec![1, 2, 3, 4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn common_ancestor_not_subset() {
|
|
||||||
let ancestor = Scope(vec![1, 2, 3, 4, 5]);
|
|
||||||
|
|
||||||
let descendant = Scope(vec![1, 2, 3, 7, 8]);
|
|
||||||
|
|
||||||
let result = ancestor.common_ancestor(&descendant);
|
|
||||||
|
|
||||||
assert_eq!(result, Scope(vec![1, 2, 3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn common_ancestor_not_found() {
|
|
||||||
let ancestor = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let descendant = Scope(vec![4, 5, 6]);
|
|
||||||
|
|
||||||
let result = ancestor.common_ancestor(&descendant);
|
|
||||||
|
|
||||||
assert_eq!(result, Scope::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn common_ancestor_no_shared_values() {
|
|
||||||
let ancestor = Scope(vec![1, 2, 3]);
|
|
||||||
|
|
||||||
let descendant = Scope(vec![4, 5, 6]);
|
|
||||||
|
|
||||||
let result = ancestor.common_ancestor(&descendant);
|
|
||||||
|
|
||||||
assert_eq!(result, Scope::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn replace_same_value() {
|
|
||||||
let mut value = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
let replacement = Scope(vec![1, 2, 3, 4, 5, 6]);
|
|
||||||
|
|
||||||
value.replace(replacement);
|
|
||||||
|
|
||||||
assert_eq!(value, Scope(vec![1, 2, 3, 4, 5, 6]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn replace_with_pattern() {
|
|
||||||
let mut value = Scope(vec![1, 2, 3, 4, 5]);
|
|
||||||
|
|
||||||
let replacement = Scope(vec![1, 2, 8, 9]);
|
|
||||||
|
|
||||||
value.replace(replacement);
|
|
||||||
|
|
||||||
assert_eq!(value, Scope(vec![1, 2, 8, 9, 3, 4, 5]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn replace_with_no_pattern() {
|
|
||||||
let mut value = Scope(vec![1, 2, 3, 4, 5]);
|
|
||||||
|
|
||||||
let replacement = Scope(vec![8, 9]);
|
|
||||||
|
|
||||||
value.replace(replacement);
|
|
||||||
|
|
||||||
assert_eq!(value, Scope(vec![8, 9, 1, 2, 3, 4, 5]));
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue