Skip to content

Commit c670b2b

Browse files
authored
remove AsLocItem trait (#1169)
1 parent 4538190 commit c670b2b

19 files changed

+108
-121
lines changed

src/errors/line_error.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ impl ValError {
6161
}
6262

6363
/// helper function to call with_outer on line items if applicable
64-
pub fn with_outer_location(self, loc_item: LocItem) -> Self {
64+
pub fn with_outer_location(self, into_loc_item: impl Into<LocItem>) -> Self {
65+
let loc_item = into_loc_item.into();
6566
match self {
6667
Self::LineErrors(mut line_errors) => {
6768
for line_error in &mut line_errors {
@@ -120,8 +121,8 @@ impl ValLineError {
120121

121122
/// location is stored reversed so it's quicker to add "outer" items as that's what we always do
122123
/// hence `push` here instead of `insert`
123-
pub fn with_outer_location(mut self, loc_item: LocItem) -> Self {
124-
self.location.with_outer(loc_item);
124+
pub fn with_outer_location(mut self, into_loc_item: impl Into<LocItem>) -> Self {
125+
self.location.with_outer(into_loc_item.into());
125126
self
126127
}
127128

src/errors/location.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ impl fmt::Display for LocItem {
3434
}
3535
}
3636

37-
// TODO rename to ToLocItem
38-
pub trait AsLocItem {
39-
// TODO rename to to_loc_item
40-
fn as_loc_item(&self) -> LocItem;
41-
}
42-
4337
impl From<String> for LocItem {
4438
fn from(s: String) -> Self {
4539
Self::S(s)
4640
}
4741
}
4842

43+
impl From<&String> for LocItem {
44+
fn from(s: &String) -> Self {
45+
s.to_string().into()
46+
}
47+
}
48+
4949
impl From<&str> for LocItem {
5050
fn from(s: &str) -> Self {
5151
Self::S(s.to_string())
@@ -201,9 +201,9 @@ impl TryFrom<Option<&PyAny>> for Location {
201201
fn try_from(location: Option<&PyAny>) -> PyResult<Self> {
202202
if let Some(location) = location {
203203
let mut loc_vec: Vec<LocItem> = if let Ok(tuple) = location.downcast::<PyTuple>() {
204-
tuple.iter().map(AsLocItem::as_loc_item).collect()
204+
tuple.iter().map(Into::into).collect()
205205
} else if let Ok(list) = location.downcast::<PyList>() {
206-
list.iter().map(AsLocItem::as_loc_item).collect()
206+
list.iter().map(Into::into).collect()
207207
} else {
208208
return Err(PyTypeError::new_err(
209209
"Location must be a list or tuple of strings and ints",

src/errors/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod validation_exception;
77
mod value_exception;
88

99
pub use self::line_error::{AsErrorValue, InputValue, ValError, ValLineError, ValResult};
10-
pub use self::location::{AsLocItem, LocItem};
10+
pub use self::location::LocItem;
1111
pub use self::types::{list_all_errors, ErrorType, ErrorTypeDefaults, Number};
1212
pub use self::validation_exception::ValidationError;
1313
pub use self::value_exception::{PydanticCustomError, PydanticKnownError, PydanticOmit, PydanticUseDefault};

src/input/input_abstract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use pyo3::exceptions::PyValueError;
44
use pyo3::types::{PyDict, PyType};
55
use pyo3::{intern, prelude::*};
66

7-
use crate::errors::{AsLocItem, ErrorTypeDefaults, InputValue, ValError, ValResult};
7+
use crate::errors::{ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
88
use crate::tools::py_err;
99
use crate::{PyMultiHostUrl, PyUrl};
1010

@@ -46,7 +46,7 @@ impl TryFrom<&str> for InputType {
4646
/// the convention is to either implement:
4747
/// * `strict_*` & `lax_*` if they have different behavior
4848
/// * or, `validate_*` and `strict_*` to just call `validate_*` if the behavior for strict and lax is the same
49-
pub trait Input<'a>: fmt::Debug + ToPyObject + AsLocItem + Sized {
49+
pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
5050
fn as_error_value(&self) -> InputValue;
5151

5252
fn identity(&self) -> Option<usize> {

src/input/input_json.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use pyo3::types::{PyDict, PyString};
66
use speedate::MicrosecondsPrecisionOverflowBehavior;
77
use strum::EnumMessage;
88

9-
use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
9+
use crate::errors::{ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
1010
use crate::validators::decimal::create_decimal;
1111

1212
use super::datetime::{
@@ -21,19 +21,19 @@ use super::{
2121
};
2222

2323
/// This is required but since JSON object keys are always strings, I don't think it can be called
24-
impl AsLocItem for JsonValue {
25-
fn as_loc_item(&self) -> LocItem {
26-
match self {
24+
impl From<&JsonValue> for LocItem {
25+
fn from(json_value: &JsonValue) -> Self {
26+
match json_value {
2727
JsonValue::Int(i) => (*i).into(),
2828
JsonValue::Str(s) => s.as_str().into(),
2929
v => format!("{v:?}").into(),
3030
}
3131
}
3232
}
3333

34-
impl AsLocItem for &JsonValue {
35-
fn as_loc_item(&self) -> LocItem {
36-
AsLocItem::as_loc_item(*self)
34+
impl From<JsonValue> for LocItem {
35+
fn from(json_value: JsonValue) -> Self {
36+
(&json_value).into()
3737
}
3838
}
3939

@@ -84,13 +84,6 @@ impl<'a> Input<'a> for JsonValue {
8484
}
8585
}
8686

87-
fn exact_str(&'a self) -> ValResult<EitherString<'a>> {
88-
match self {
89-
JsonValue::Str(s) => Ok(s.as_str().into()),
90-
_ => Err(ValError::new(ErrorTypeDefaults::StringType, self)),
91-
}
92-
}
93-
9487
fn validate_str(
9588
&'a self,
9689
strict: bool,
@@ -144,6 +137,13 @@ impl<'a> Input<'a> for JsonValue {
144137
}
145138
}
146139

140+
fn exact_str(&'a self) -> ValResult<EitherString<'a>> {
141+
match self {
142+
JsonValue::Str(s) => Ok(s.as_str().into()),
143+
_ => Err(ValError::new(ErrorTypeDefaults::StringType, self)),
144+
}
145+
}
146+
147147
fn validate_float(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherFloat<'a>>> {
148148
match self {
149149
JsonValue::Float(f) => Ok(ValidationMatch::exact(EitherFloat::F64(*f))),
@@ -319,18 +319,6 @@ impl BorrowInput for &'_ JsonValue {
319319
}
320320
}
321321

322-
impl AsLocItem for String {
323-
fn as_loc_item(&self) -> LocItem {
324-
self.to_string().into()
325-
}
326-
}
327-
328-
impl AsLocItem for &String {
329-
fn as_loc_item(&self) -> LocItem {
330-
AsLocItem::as_loc_item(*self)
331-
}
332-
}
333-
334322
/// Required for JSON Object keys so the string can behave like an Input
335323
impl<'a> Input<'a> for String {
336324
fn as_error_value(&self) -> InputValue {

src/input/input_python.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use pyo3::{intern, PyTypeInfo};
1212

1313
use speedate::MicrosecondsPrecisionOverflowBehavior;
1414

15-
use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
15+
use crate::errors::{ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
1616
use crate::tools::{extract_i64, safe_repr};
1717
use crate::validators::decimal::{create_decimal, get_decimal_type};
1818
use crate::validators::Exactness;
@@ -92,21 +92,21 @@ macro_rules! extract_dict_items {
9292
};
9393
}
9494

95-
impl AsLocItem for PyAny {
96-
fn as_loc_item(&self) -> LocItem {
97-
if let Ok(py_str) = self.downcast::<PyString>() {
95+
impl From<&PyAny> for LocItem {
96+
fn from(py_any: &PyAny) -> Self {
97+
if let Ok(py_str) = py_any.downcast::<PyString>() {
9898
py_str.to_string_lossy().as_ref().into()
99-
} else if let Some(key_int) = extract_i64(self) {
99+
} else if let Some(key_int) = extract_i64(py_any) {
100100
key_int.into()
101101
} else {
102-
safe_repr(self).to_string().into()
102+
safe_repr(py_any).to_string().into()
103103
}
104104
}
105105
}
106106

107-
impl AsLocItem for &'_ PyAny {
108-
fn as_loc_item(&self) -> LocItem {
109-
AsLocItem::as_loc_item(*self)
107+
impl From<PyAny> for LocItem {
108+
fn from(py_any: PyAny) -> Self {
109+
(&py_any).into()
110110
}
111111
}
112112

@@ -244,22 +244,6 @@ impl<'a> Input<'a> for PyAny {
244244
Err(ValError::new(ErrorTypeDefaults::StringType, self))
245245
}
246246

247-
fn exact_str(&'a self) -> ValResult<EitherString<'a>> {
248-
if let Ok(py_str) = <PyString as PyTryFrom>::try_from_exact(self) {
249-
Ok(EitherString::Py(py_str))
250-
} else {
251-
Err(ValError::new(ErrorTypeDefaults::IntType, self))
252-
}
253-
}
254-
255-
fn exact_int(&'a self) -> ValResult<EitherInt<'a>> {
256-
if PyInt::is_exact_type_of(self) {
257-
Ok(EitherInt::Py(self))
258-
} else {
259-
Err(ValError::new(ErrorTypeDefaults::IntType, self))
260-
}
261-
}
262-
263247
fn validate_bytes(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherBytes<'a>>> {
264248
if let Ok(py_bytes) = self.downcast_exact::<PyBytes>() {
265249
return Ok(ValidationMatch::exact(py_bytes.into()));
@@ -347,6 +331,22 @@ impl<'a> Input<'a> for PyAny {
347331
Err(ValError::new(ErrorTypeDefaults::IntType, self))
348332
}
349333

334+
fn exact_int(&'a self) -> ValResult<EitherInt<'a>> {
335+
if PyInt::is_exact_type_of(self) {
336+
Ok(EitherInt::Py(self))
337+
} else {
338+
Err(ValError::new(ErrorTypeDefaults::IntType, self))
339+
}
340+
}
341+
342+
fn exact_str(&'a self) -> ValResult<EitherString<'a>> {
343+
if let Ok(py_str) = <PyString as PyTryFrom>::try_from_exact(self) {
344+
Ok(EitherString::Py(py_str))
345+
} else {
346+
Err(ValError::new(ErrorTypeDefaults::IntType, self))
347+
}
348+
}
349+
350350
fn validate_float(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherFloat<'a>>> {
351351
if let Ok(float) = self.downcast_exact::<PyFloat>() {
352352
return Ok(ValidationMatch::exact(EitherFloat::Py(float)));

src/input/input_string.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use pyo3::types::{PyDict, PyString};
33

44
use speedate::MicrosecondsPrecisionOverflowBehavior;
55

6-
use crate::errors::{AsLocItem, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
6+
use crate::errors::{ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
77
use crate::input::py_string_str;
88
use crate::tools::safe_repr;
99
use crate::validators::decimal::create_decimal;
@@ -17,7 +17,7 @@ use super::{
1717
GenericIterator, GenericMapping, Input, ValidationMatch,
1818
};
1919

20-
#[derive(Debug)]
20+
#[derive(Debug, Clone)]
2121
pub enum StringMapping<'py> {
2222
String(&'py PyString),
2323
Mapping(&'py PyDict),
@@ -52,11 +52,11 @@ impl<'py> StringMapping<'py> {
5252
}
5353
}
5454

55-
impl AsLocItem for StringMapping<'_> {
56-
fn as_loc_item(&self) -> LocItem {
57-
match self {
58-
Self::String(s) => s.to_string_lossy().as_ref().into(),
59-
Self::Mapping(d) => safe_repr(d).to_string().into(),
55+
impl From<StringMapping<'_>> for LocItem {
56+
fn from(string_mapping: StringMapping<'_>) -> Self {
57+
match string_mapping {
58+
StringMapping::String(s) => s.to_string_lossy().as_ref().into(),
59+
StringMapping::Mapping(d) => safe_repr(d).to_string().into(),
6060
}
6161
}
6262
}

src/input/return_enums.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ fn validate_iter_to_vec<'a, 's>(
205205
}
206206
Err(ValError::LineErrors(line_errors)) => {
207207
max_length_check.incr()?;
208-
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into())));
208+
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index)));
209209
}
210210
Err(ValError::Omit) => (),
211211
Err(err) => return Err(err),
@@ -284,7 +284,7 @@ fn validate_iter_to_set<'a, 's>(
284284
}
285285
}
286286
Err(ValError::LineErrors(line_errors)) => {
287-
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into())));
287+
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index)));
288288
}
289289
Err(ValError::Omit) => (),
290290
Err(err) => return Err(err),

src/lookup_key.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,11 @@ impl LookupPath {
366366
pub fn apply_error_loc(&self, mut line_error: ValLineError, loc_by_alias: bool, field_name: &str) -> ValLineError {
367367
if loc_by_alias {
368368
for path_item in self.iter().rev() {
369-
line_error = line_error.with_outer_location(path_item.clone().into());
369+
line_error = line_error.with_outer_location(path_item.clone());
370370
}
371371
line_error
372372
} else {
373-
line_error.with_outer_location(field_name.to_string().into())
373+
line_error.with_outer_location(field_name)
374374
}
375375
}
376376

src/validators/arguments.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ahash::AHashSet;
66

77
use crate::build_tools::py_schema_err;
88
use crate::build_tools::{schema_or_config_same, ExtraBehavior};
9-
use crate::errors::{AsLocItem, ErrorTypeDefaults, ValError, ValLineError, ValResult};
9+
use crate::errors::{ErrorTypeDefaults, ValError, ValLineError, ValResult};
1010
use crate::input::{GenericArguments, Input, ValidationMatch};
1111
use crate::lookup_key::LookupKey;
1212

@@ -209,7 +209,7 @@ impl Validator for ArgumentsValidator {
209209
{
210210
Ok(value) => output_args.push(value),
211211
Err(ValError::LineErrors(line_errors)) => {
212-
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into())));
212+
errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index)));
213213
}
214214
Err(err) => return Err(err),
215215
}
@@ -263,7 +263,7 @@ impl Validator for ArgumentsValidator {
263263
errors.extend(
264264
line_errors
265265
.into_iter()
266-
.map(|err| err.with_outer_location((index + self.positional_params_count).into())),
266+
.map(|err| err.with_outer_location(index + self.positional_params_count)),
267267
);
268268
}
269269
Err(err) => return Err(err),
@@ -289,7 +289,7 @@ impl Validator for ArgumentsValidator {
289289
Err(ValError::LineErrors(line_errors)) => {
290290
for err in line_errors {
291291
errors.push(
292-
err.with_outer_location(raw_key.as_loc_item())
292+
err.with_outer_location(raw_key)
293293
.with_type(ErrorTypeDefaults::InvalidKey),
294294
);
295295
}
@@ -303,7 +303,7 @@ impl Validator for ArgumentsValidator {
303303
Ok(value) => output_kwargs.set_item(either_str.as_py_string(py), value)?,
304304
Err(ValError::LineErrors(line_errors)) => {
305305
for err in line_errors {
306-
errors.push(err.with_outer_location(raw_key.as_loc_item()));
306+
errors.push(err.with_outer_location(raw_key));
307307
}
308308
}
309309
Err(err) => return Err(err),
@@ -313,7 +313,7 @@ impl Validator for ArgumentsValidator {
313313
errors.push(ValLineError::new_with_loc(
314314
ErrorTypeDefaults::UnexpectedKeywordArgument,
315315
value,
316-
raw_key.as_loc_item(),
316+
raw_key,
317317
));
318318
}
319319
}

src/validators/call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl Validator for CallValidator {
9393
if let Some(return_validator) = &self.return_validator {
9494
return_validator
9595
.validate(py, return_value.into_ref(py), state)
96-
.map_err(|e| e.with_outer_location("return".into()))
96+
.map_err(|e| e.with_outer_location("return"))
9797
} else {
9898
Ok(return_value.to_object(py))
9999
}

0 commit comments

Comments
 (0)