mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
Object field order matters!
This commit is contained in:
parent
3d1ce384d0
commit
48c1381194
@ -28,14 +28,8 @@ pub fn assign(from: &Data, target: &Data) {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::object::Object>(),
|
.downcast_ref::<crate::data::object::Object>(),
|
||||||
) {
|
) {
|
||||||
for (field, target) in target.0.iter() {
|
for ((_, from), (_, target)) in from.0.iter().zip(target.0.iter()) {
|
||||||
for (name, from) in from.0.iter() {
|
|
||||||
// TODO: do string comparison at compile-time instead!
|
|
||||||
if field == name {
|
|
||||||
assign(from, target);
|
assign(from, target);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!("invalid assignment")
|
unreachable!("invalid assignment")
|
||||||
|
@ -21,26 +21,17 @@ impl MersStatement for Object {
|
|||||||
init_to: Option<&Type>,
|
init_to: Option<&Type>,
|
||||||
) -> Result<data::Type, super::CheckError> {
|
) -> Result<data::Type, super::CheckError> {
|
||||||
let mut assign_types = if let Some(init_to) = init_to {
|
let mut assign_types = if let Some(init_to) = init_to {
|
||||||
|
let mut acc = (0..self.elems.len())
|
||||||
|
.map(|_| Type::empty())
|
||||||
|
.collect::<VecDeque<_>>();
|
||||||
let print_is_part_of = init_to.types.len() > 1;
|
let print_is_part_of = init_to.types.len() > 1;
|
||||||
Some(
|
|
||||||
self.elems
|
|
||||||
.iter()
|
|
||||||
.map(|(field, _)| -> Result<_, CheckError> {
|
|
||||||
let mut acc = Type::empty();
|
|
||||||
for t in init_to.types.iter() {
|
for t in init_to.types.iter() {
|
||||||
if let Some(t) = t.as_any().downcast_ref::<ObjectT>() {
|
if let Some(t) = t.as_any().downcast_ref::<ObjectT>() {
|
||||||
let mut found = false;
|
if self.elems.len() == t.0.len() {
|
||||||
for (name, assign_to) in t.0.iter() {
|
for (i, ((sn, _), (tn, t))) in self.elems.iter().zip(t.0.iter()).enumerate()
|
||||||
if name == field {
|
{
|
||||||
acc.add(Arc::new(assign_to.clone()));
|
if sn != tn {
|
||||||
found = true;
|
return Err(format!("can't init an {} with type {}{} - field mismatch: {sn} != {tn}", "object".color(error_colors::InitTo),
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return Err(format!(
|
|
||||||
"can't init an {} with type {}{} - field {field} not found",
|
|
||||||
"object".color(error_colors::InitTo),
|
|
||||||
t.to_string().color(error_colors::InitFrom),
|
t.to_string().color(error_colors::InitFrom),
|
||||||
if print_is_part_of {
|
if print_is_part_of {
|
||||||
format!(
|
format!(
|
||||||
@ -52,6 +43,41 @@ impl MersStatement for Object {
|
|||||||
}
|
}
|
||||||
).into());
|
).into());
|
||||||
}
|
}
|
||||||
|
acc[i].add(Arc::new(t.clone()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"can't init an {} with type {}{} - source has {}",
|
||||||
|
"object".color(error_colors::InitTo),
|
||||||
|
t.to_string().color(error_colors::InitFrom),
|
||||||
|
if print_is_part_of {
|
||||||
|
format!(
|
||||||
|
", which is part of {}",
|
||||||
|
init_to.to_string().color(error_colors::InitFrom)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!("")
|
||||||
|
},
|
||||||
|
if self.elems.len() > t.0.len() {
|
||||||
|
format!("less fields ({}, not {})", t.0.len(), self.elems.len())
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"more fields. Either ignore those fields (`{}`) - or remove them from the type (`... := [{}] ...`)",
|
||||||
|
t.0.iter()
|
||||||
|
.skip(self.elems.len())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, (n, _))| if i == 0 {
|
||||||
|
format!("{n}: _")
|
||||||
|
} else {
|
||||||
|
format!(", {n}: _")
|
||||||
|
})
|
||||||
|
.collect::<String>(),
|
||||||
|
data::object::ObjectT(t.0.iter().take(self.elems.len()).cloned().collect())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"can't init an {} with type {}{} - only objects can be assigned to objects",
|
"can't init an {} with type {}{} - only objects can be assigned to objects",
|
||||||
@ -65,13 +91,11 @@ impl MersStatement for Object {
|
|||||||
} else {
|
} else {
|
||||||
format!("")
|
format!("")
|
||||||
}
|
}
|
||||||
).into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(acc)
|
|
||||||
})
|
|
||||||
.collect::<Result<VecDeque<Type>, CheckError>>()?,
|
|
||||||
)
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(acc)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user