feat: initial attempt at making reflection more flexible
This commit is contained in:
parent
35cfef7cf2
commit
df4b1c6ed4
@ -6,7 +6,7 @@ use core::fmt;
|
|||||||
use super::error::AccessErrorKind;
|
use super::error::AccessErrorKind;
|
||||||
use crate::{AccessError, PartialReflect, ReflectKind, ReflectMut, ReflectRef, VariantType};
|
use crate::{AccessError, PartialReflect, ReflectKind, ReflectMut, ReflectRef, VariantType};
|
||||||
|
|
||||||
type InnerResult<T> = Result<T, AccessErrorKind>;
|
type InnerResult<'a, T> = Result<T, AccessErrorKind<'a>>;
|
||||||
|
|
||||||
/// A singular element access within a path.
|
/// A singular element access within a path.
|
||||||
/// Multiple accesses can be combined into a [`ParsedPath`](super::ParsedPath).
|
/// Multiple accesses can be combined into a [`ParsedPath`](super::ParsedPath).
|
||||||
@ -60,49 +60,94 @@ impl<'a> Access<'a> {
|
|||||||
.map_err(|err| err.with_access(self.clone(), offset))
|
.map_err(|err| err.with_access(self.clone(), offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_parse_field_as_index(
|
||||||
|
base: impl Fn() -> ReflectKind,
|
||||||
|
field: Cow<'a, str>,
|
||||||
|
) -> Result<usize, AccessErrorKind<'a>> {
|
||||||
|
field
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| AccessErrorKind::UnsupportedAccess {
|
||||||
|
base: base(),
|
||||||
|
access: Access::Field(field),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn element_inner<'r>(
|
fn element_inner<'r>(
|
||||||
&self,
|
&self,
|
||||||
base: &'r dyn PartialReflect,
|
base: &'r dyn PartialReflect,
|
||||||
) -> InnerResult<Option<&'r dyn PartialReflect>> {
|
) -> InnerResult<'a, Option<&'r dyn PartialReflect>> {
|
||||||
use ReflectRef::*;
|
use ReflectRef::*;
|
||||||
|
|
||||||
let invalid_variant =
|
let invalid_variant =
|
||||||
|expected, actual| AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual };
|
|expected, actual| AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual };
|
||||||
|
|
||||||
match (self, base.reflect_ref()) {
|
match (base.reflect_ref(), self) {
|
||||||
(Self::Field(field), Struct(struct_ref)) => Ok(struct_ref.field(field.as_ref())),
|
// Struct
|
||||||
(Self::Field(field), Enum(enum_ref)) => match enum_ref.variant_type() {
|
(Struct(struct_ref), Access::Field(field)) => Ok(struct_ref.field(field.as_ref())),
|
||||||
|
(Struct(struct_ref), &Access::FieldIndex(index)) => Ok(struct_ref.field_at(index)),
|
||||||
|
// Tuple Struct
|
||||||
|
(TupleStruct(struct_ref), Access::Field(field)) => Ok(struct_ref.field(
|
||||||
|
Self::try_parse_field_as_index(|| struct_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
TupleStruct(struct_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(struct_ref.field(index)),
|
||||||
|
// Tuple
|
||||||
|
(Tuple(tuple_ref), Access::Field(field)) => Ok(tuple_ref.field(
|
||||||
|
Self::try_parse_field_as_index(|| tuple_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
Tuple(tuple_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(tuple_ref.field(index)),
|
||||||
|
// List
|
||||||
|
(List(list_ref), Access::Field(field)) => Ok(list_ref.get(
|
||||||
|
Self::try_parse_field_as_index(|| list_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
List(list_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(list_ref.get(index)),
|
||||||
|
// Array
|
||||||
|
(Array(array_ref), Access::Field(field)) => Ok(array_ref.get(
|
||||||
|
Self::try_parse_field_as_index(|| array_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
Array(array_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(array_ref.get(index)),
|
||||||
|
// Map
|
||||||
|
(Map(map_ref), Access::Field(field)) => Ok(map_ref.get(&field.clone().into_owned())),
|
||||||
|
(
|
||||||
|
Map(map_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(map_ref.get(&index)),
|
||||||
|
// Set
|
||||||
|
(Set(set_ref), Access::Field(field)) => Ok(set_ref.get(&field.clone().into_owned())),
|
||||||
|
(
|
||||||
|
Set(set_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(set_ref.get(&index)),
|
||||||
|
// Enum
|
||||||
|
(Enum(enum_ref), Access::Field(field)) => match enum_ref.variant_type() {
|
||||||
VariantType::Struct => Ok(enum_ref.field(field.as_ref())),
|
VariantType::Struct => Ok(enum_ref.field(field.as_ref())),
|
||||||
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
||||||
},
|
},
|
||||||
(&Self::FieldIndex(index), Struct(struct_ref)) => Ok(struct_ref.field_at(index)),
|
(Enum(enum_ref), &Access::FieldIndex(index)) => match enum_ref.variant_type() {
|
||||||
(&Self::FieldIndex(index), Enum(enum_ref)) => match enum_ref.variant_type() {
|
|
||||||
VariantType::Struct => Ok(enum_ref.field_at(index)),
|
VariantType::Struct => Ok(enum_ref.field_at(index)),
|
||||||
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
||||||
},
|
},
|
||||||
(Self::Field(_) | Self::FieldIndex(_), actual) => {
|
(Enum(enum_ref), &Access::TupleIndex(index) | &Access::ListIndex(index)) => {
|
||||||
Err(AccessErrorKind::IncompatibleTypes {
|
match enum_ref.variant_type() {
|
||||||
expected: ReflectKind::Struct,
|
VariantType::Tuple => Ok(enum_ref.field_at(index)),
|
||||||
actual: actual.into(),
|
actual => Err(invalid_variant(VariantType::Tuple, actual)),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
(other, access) => Err(AccessErrorKind::UnsupportedAccess {
|
||||||
(&Self::TupleIndex(index), TupleStruct(tuple)) => Ok(tuple.field(index)),
|
base: other.kind(),
|
||||||
(&Self::TupleIndex(index), Tuple(tuple)) => Ok(tuple.field(index)),
|
access: access.clone().into_owned(),
|
||||||
(&Self::TupleIndex(index), Enum(enum_ref)) => match enum_ref.variant_type() {
|
|
||||||
VariantType::Tuple => Ok(enum_ref.field_at(index)),
|
|
||||||
actual => Err(invalid_variant(VariantType::Tuple, actual)),
|
|
||||||
},
|
|
||||||
(Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
|
|
||||||
expected: ReflectKind::Tuple,
|
|
||||||
actual: actual.into(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
(&Self::ListIndex(index), List(list)) => Ok(list.get(index)),
|
|
||||||
(&Self::ListIndex(index), Array(list)) => Ok(list.get(index)),
|
|
||||||
(Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
|
|
||||||
expected: ReflectKind::List,
|
|
||||||
actual: actual.into(),
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,52 +161,90 @@ impl<'a> Access<'a> {
|
|||||||
|
|
||||||
self.element_inner_mut(base)
|
self.element_inner_mut(base)
|
||||||
.and_then(|maybe| maybe.ok_or(AccessErrorKind::MissingField(kind)))
|
.and_then(|maybe| maybe.ok_or(AccessErrorKind::MissingField(kind)))
|
||||||
.map_err(|err| err.with_access(self.clone(), offset))
|
.map_err(move |err| err.with_access(self.clone(), offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn element_inner_mut<'r>(
|
fn element_inner_mut<'r>(
|
||||||
&self,
|
&self,
|
||||||
base: &'r mut dyn PartialReflect,
|
base: &'r mut dyn PartialReflect,
|
||||||
) -> InnerResult<Option<&'r mut dyn PartialReflect>> {
|
) -> InnerResult<'a, Option<&'r mut dyn PartialReflect>> {
|
||||||
use ReflectMut::*;
|
use ReflectMut::*;
|
||||||
|
|
||||||
let invalid_variant =
|
let invalid_variant =
|
||||||
|expected, actual| AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual };
|
|expected, actual| AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual };
|
||||||
|
|
||||||
match (self, base.reflect_mut()) {
|
match (base.reflect_mut(), self) {
|
||||||
(Self::Field(field), Struct(struct_mut)) => Ok(struct_mut.field_mut(field.as_ref())),
|
// Struct
|
||||||
(Self::Field(field), Enum(enum_mut)) => match enum_mut.variant_type() {
|
(Struct(struct_ref), Access::Field(field)) => Ok(struct_ref.field_mut(field.as_ref())),
|
||||||
VariantType::Struct => Ok(enum_mut.field_mut(field.as_ref())),
|
(
|
||||||
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
Struct(struct_ref),
|
||||||
},
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
(&Self::FieldIndex(index), Struct(struct_mut)) => Ok(struct_mut.field_at_mut(index)),
|
) => Ok(struct_ref.field_at_mut(index)),
|
||||||
(&Self::FieldIndex(index), Enum(enum_mut)) => match enum_mut.variant_type() {
|
// Tuple Struct
|
||||||
VariantType::Struct => Ok(enum_mut.field_at_mut(index)),
|
(TupleStruct(struct_ref), Access::Field(field)) => Ok(struct_ref.field_mut(
|
||||||
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
Self::try_parse_field_as_index(|| struct_ref.reflect_kind(), field.clone())?,
|
||||||
},
|
)),
|
||||||
(Self::Field(_) | Self::FieldIndex(_), actual) => {
|
(
|
||||||
Err(AccessErrorKind::IncompatibleTypes {
|
TupleStruct(struct_ref),
|
||||||
expected: ReflectKind::Struct,
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
actual: actual.into(),
|
) => Ok(struct_ref.field_mut(index)),
|
||||||
})
|
// Tuple
|
||||||
|
(Tuple(tuple_ref), Access::Field(field)) => Ok(tuple_ref.field_mut(
|
||||||
|
Self::try_parse_field_as_index(|| tuple_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
Tuple(tuple_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(tuple_ref.field_mut(index)),
|
||||||
|
// List
|
||||||
|
(List(list_ref), Access::Field(field)) => Ok(list_ref.get_mut(
|
||||||
|
Self::try_parse_field_as_index(|| list_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
List(list_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(list_ref.get_mut(index)),
|
||||||
|
// Array
|
||||||
|
(Array(array_ref), Access::Field(field)) => Ok(array_ref.get_mut(
|
||||||
|
Self::try_parse_field_as_index(|| array_ref.reflect_kind(), field.clone())?,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
Array(array_ref),
|
||||||
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
) => Ok(array_ref.get_mut(index)),
|
||||||
|
// Map
|
||||||
|
(Map(map_ref), Access::Field(field)) => {
|
||||||
|
Ok(map_ref.get_mut(&field.clone().into_owned()))
|
||||||
}
|
}
|
||||||
|
(
|
||||||
(&Self::TupleIndex(index), TupleStruct(tuple)) => Ok(tuple.field_mut(index)),
|
Map(map_ref),
|
||||||
(&Self::TupleIndex(index), Tuple(tuple)) => Ok(tuple.field_mut(index)),
|
&Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
(&Self::TupleIndex(index), Enum(enum_mut)) => match enum_mut.variant_type() {
|
) => Ok(map_ref.get_mut(&index)),
|
||||||
VariantType::Tuple => Ok(enum_mut.field_at_mut(index)),
|
// Set - no get_mut
|
||||||
actual => Err(invalid_variant(VariantType::Tuple, actual)),
|
// (Set(set_ref), Access::Field(field)) => Ok(set_ref.get(&field.clone().into_owned())),
|
||||||
|
// (
|
||||||
|
// Set(set_ref),
|
||||||
|
// &Access::FieldIndex(index) | &Access::TupleIndex(index) | &Access::ListIndex(index),
|
||||||
|
// ) => Ok(set_ref.get(&index)),
|
||||||
|
// Enum
|
||||||
|
// Enum
|
||||||
|
(Enum(enum_ref), Access::Field(field)) => match enum_ref.variant_type() {
|
||||||
|
VariantType::Struct => Ok(enum_ref.field_mut(field.as_ref())),
|
||||||
|
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
||||||
},
|
},
|
||||||
(Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
|
(Enum(enum_ref), &Access::FieldIndex(index)) => match enum_ref.variant_type() {
|
||||||
expected: ReflectKind::Tuple,
|
VariantType::Struct => Ok(enum_ref.field_at_mut(index)),
|
||||||
actual: actual.into(),
|
actual => Err(invalid_variant(VariantType::Struct, actual)),
|
||||||
}),
|
},
|
||||||
|
(Enum(enum_ref), &Access::TupleIndex(index) | &Access::ListIndex(index)) => {
|
||||||
(&Self::ListIndex(index), List(list)) => Ok(list.get_mut(index)),
|
match enum_ref.variant_type() {
|
||||||
(&Self::ListIndex(index), Array(list)) => Ok(list.get_mut(index)),
|
VariantType::Tuple => Ok(enum_ref.field_at_mut(index)),
|
||||||
(Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
|
actual => Err(invalid_variant(VariantType::Tuple, actual)),
|
||||||
expected: ReflectKind::List,
|
}
|
||||||
actual: actual.into(),
|
}
|
||||||
|
(other, access) => Err(AccessErrorKind::UnsupportedAccess {
|
||||||
|
base: other.kind(),
|
||||||
|
access: access.clone().into_owned(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,11 @@ use crate::{ReflectKind, VariantType};
|
|||||||
|
|
||||||
/// The kind of [`AccessError`], along with some kind-specific information.
|
/// The kind of [`AccessError`], along with some kind-specific information.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum AccessErrorKind {
|
pub enum AccessErrorKind<'a> {
|
||||||
/// An error that occurs when a certain type doesn't
|
/// An error that occurs when a certain type doesn't
|
||||||
/// contain the value referenced by the [`Access`].
|
/// contain the value referenced by the [`Access`].
|
||||||
MissingField(ReflectKind),
|
MissingField(ReflectKind),
|
||||||
|
|
||||||
/// An error that occurs when using an [`Access`] on the wrong type.
|
|
||||||
/// (i.e. a [`ListIndex`](Access::ListIndex) on a struct, or a [`TupleIndex`](Access::TupleIndex) on a list)
|
|
||||||
IncompatibleTypes {
|
|
||||||
/// The [`ReflectKind`] that was expected based on the [`Access`].
|
|
||||||
expected: ReflectKind,
|
|
||||||
/// The actual [`ReflectKind`] that was found.
|
|
||||||
actual: ReflectKind,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// An error that occurs when using an [`Access`] on the wrong enum variant.
|
/// An error that occurs when using an [`Access`] on the wrong enum variant.
|
||||||
/// (i.e. a [`ListIndex`](Access::ListIndex) on a struct variant, or a [`TupleIndex`](Access::TupleIndex) on a unit variant)
|
/// (i.e. a [`ListIndex`](Access::ListIndex) on a struct variant, or a [`TupleIndex`](Access::TupleIndex) on a unit variant)
|
||||||
IncompatibleEnumVariantTypes {
|
IncompatibleEnumVariantTypes {
|
||||||
@ -27,10 +18,25 @@ pub enum AccessErrorKind {
|
|||||||
/// The actual [`VariantType`] that was found.
|
/// The actual [`VariantType`] that was found.
|
||||||
actual: VariantType,
|
actual: VariantType,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Occurs when an [`Access`] is attempted on a type that does not support it.
|
||||||
|
UnsupportedAccess {
|
||||||
|
/// The [`ReflectKind`] that was attempted to be accessed.
|
||||||
|
base: ReflectKind,
|
||||||
|
/// The [`Access`] that was attempted.
|
||||||
|
access: Access<'a>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccessErrorKind {
|
impl AccessErrorKind<'_> {
|
||||||
pub(super) fn with_access(self, access: Access, offset: Option<usize>) -> AccessError {
|
pub(super) fn with_access<'a>(
|
||||||
|
self,
|
||||||
|
access: Access<'a>,
|
||||||
|
offset: Option<usize>,
|
||||||
|
) -> AccessError<'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
AccessError {
|
AccessError {
|
||||||
kind: self,
|
kind: self,
|
||||||
access,
|
access,
|
||||||
@ -52,7 +58,7 @@ impl AccessErrorKind {
|
|||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct AccessError<'a> {
|
pub struct AccessError<'a> {
|
||||||
pub(super) kind: AccessErrorKind,
|
pub(super) kind: AccessErrorKind<'a>,
|
||||||
pub(super) access: Access<'a>,
|
pub(super) access: Access<'a>,
|
||||||
pub(super) offset: Option<usize>,
|
pub(super) offset: Option<usize>,
|
||||||
}
|
}
|
||||||
@ -112,11 +118,11 @@ impl fmt::Display for AccessError<'_> {
|
|||||||
access.display_value()
|
access.display_value()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
AccessErrorKind::IncompatibleTypes { expected, actual } => write!(
|
AccessErrorKind::UnsupportedAccess { base, access } => write!(
|
||||||
f,
|
f,
|
||||||
"Expected {} access to access a {expected}, found a {actual} instead.",
|
"Tried to access {base} with {} access: '{access}'",
|
||||||
access.kind()
|
access.kind(),
|
||||||
),
|
),
|
||||||
AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual } => write!(
|
AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual } => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -513,6 +513,7 @@ impl core::ops::IndexMut<usize> for ParsedPath {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use alloc::string::String;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
|
|
||||||
#[derive(Reflect, PartialEq, Debug)]
|
#[derive(Reflect, PartialEq, Debug)]
|
||||||
@ -526,6 +527,8 @@ mod tests {
|
|||||||
struct_variant: F,
|
struct_variant: F,
|
||||||
array: [i32; 3],
|
array: [i32; 3],
|
||||||
tuple: (bool, f32),
|
tuple: (bool, f32),
|
||||||
|
string_map: std::collections::HashMap<String, String>,
|
||||||
|
usize_map: std::collections::HashMap<usize, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Reflect, PartialEq, Debug)]
|
#[derive(Reflect, PartialEq, Debug)]
|
||||||
@ -566,6 +569,10 @@ mod tests {
|
|||||||
struct_variant: F::Şķràźÿ { 東京: 'm' },
|
struct_variant: F::Şķràźÿ { 東京: 'm' },
|
||||||
array: [86, 75, 309],
|
array: [86, 75, 309],
|
||||||
tuple: (true, 1.23),
|
tuple: (true, 1.23),
|
||||||
|
string_map: vec![("foo".into(), "bar".into()), ("baz".into(), "qux".into())]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
usize_map: vec![(0, 1), (1, 2), (2, 3)].into_iter().collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,14 +589,19 @@ mod tests {
|
|||||||
|
|
||||||
type StaticError = ReflectPathError<'static>;
|
type StaticError = ReflectPathError<'static>;
|
||||||
|
|
||||||
fn invalid_access(
|
fn invalid_access(offset: usize, actual: ReflectKind, access: &'static str) -> StaticError {
|
||||||
offset: usize,
|
|
||||||
actual: ReflectKind,
|
|
||||||
expected: ReflectKind,
|
|
||||||
access: &'static str,
|
|
||||||
) -> StaticError {
|
|
||||||
ReflectPathError::InvalidAccess(AccessError {
|
ReflectPathError::InvalidAccess(AccessError {
|
||||||
kind: AccessErrorKind::IncompatibleTypes { actual, expected },
|
kind: AccessErrorKind::UnsupportedAccess {
|
||||||
|
base: actual,
|
||||||
|
access: ParsedPath::parse_static(access)
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
.into_iter()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.access
|
||||||
|
.clone(),
|
||||||
|
},
|
||||||
access: ParsedPath::parse_static(access).unwrap()[1].access.clone(),
|
access: ParsedPath::parse_static(access).unwrap()[1].access.clone(),
|
||||||
offset: Some(offset),
|
offset: Some(offset),
|
||||||
})
|
})
|
||||||
@ -748,6 +760,8 @@ mod tests {
|
|||||||
assert_eq!(*a.path::<f32>("x.łørđ.mосква").unwrap(), 3.14);
|
assert_eq!(*a.path::<f32>("x.łørđ.mосква").unwrap(), 3.14);
|
||||||
assert_eq!(*a.path::<f32>("y[1].mосква").unwrap(), 2.0);
|
assert_eq!(*a.path::<f32>("y[1].mосква").unwrap(), 2.0);
|
||||||
assert_eq!(*a.path::<usize>("z.0.1").unwrap(), 42);
|
assert_eq!(*a.path::<usize>("z.0.1").unwrap(), 42);
|
||||||
|
assert_eq!(*a.path::<usize>("z.0[1]").unwrap(), 42);
|
||||||
|
assert_eq!(*a.path::<usize>("z[0][1]").unwrap(), 42);
|
||||||
assert_eq!(*a.path::<usize>("x#0").unwrap(), 10);
|
assert_eq!(*a.path::<usize>("x#0").unwrap(), 10);
|
||||||
assert_eq!(*a.path::<f32>("x#1#0").unwrap(), 3.14);
|
assert_eq!(*a.path::<f32>("x#1#0").unwrap(), 3.14);
|
||||||
|
|
||||||
@ -757,6 +771,7 @@ mod tests {
|
|||||||
assert_eq!(*a.path::<char>("struct_variant#0").unwrap(), 'm');
|
assert_eq!(*a.path::<char>("struct_variant#0").unwrap(), 'm');
|
||||||
|
|
||||||
assert_eq!(*a.path::<i32>("array[2]").unwrap(), 309);
|
assert_eq!(*a.path::<i32>("array[2]").unwrap(), 309);
|
||||||
|
assert_eq!(*a.path::<i32>("array.2").unwrap(), 309);
|
||||||
|
|
||||||
assert_eq!(*a.path::<f32>("tuple.1").unwrap(), 1.23);
|
assert_eq!(*a.path::<f32>("tuple.1").unwrap(), 1.23);
|
||||||
*a.path_mut::<f32>("tuple.1").unwrap() = 3.21;
|
*a.path_mut::<f32>("tuple.1").unwrap() = 3.21;
|
||||||
@ -768,6 +783,23 @@ mod tests {
|
|||||||
*a.path_mut::<u32>("tuple_variant.0").unwrap() = 1337;
|
*a.path_mut::<u32>("tuple_variant.0").unwrap() = 1337;
|
||||||
assert_eq!(a.tuple_variant, F::Tuple(1337, 321));
|
assert_eq!(a.tuple_variant, F::Tuple(1337, 321));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
*a.path::<String>("string_map.foo").unwrap(),
|
||||||
|
String::from("bar")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
*a.path::<String>("string_map.baz").unwrap(),
|
||||||
|
String::from("qux")
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map[0]").unwrap(), 1);
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map[1]").unwrap(), 2);
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map[2]").unwrap(), 3);
|
||||||
|
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map.0").unwrap(), 1);
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map.1").unwrap(), 2);
|
||||||
|
assert_eq!(*a.path::<usize>("usize_map.2").unwrap(), 3);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a.reflect_path("x.notreal").err().unwrap(),
|
a.reflect_path("x.notreal").err().unwrap(),
|
||||||
ReflectPathError::InvalidAccess(AccessError {
|
ReflectPathError::InvalidAccess(AccessError {
|
||||||
@ -792,11 +824,11 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a.reflect_path("x[0]").err().unwrap(),
|
a.reflect_path("x[0]").err().unwrap(),
|
||||||
invalid_access(2, ReflectKind::Struct, ReflectKind::List, "x[0]")
|
invalid_access(2, ReflectKind::Struct, "x[0]")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a.reflect_path("y.x").err().unwrap(),
|
a.reflect_path("y.x").err().unwrap(),
|
||||||
invalid_access(2, ReflectKind::List, ReflectKind::Struct, "y.x")
|
invalid_access(2, ReflectKind::List, "y.x")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user