Skip to content

Commit b40359d

Browse files
committed
Venodr nightly functions
1 parent 28f49d8 commit b40359d

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

src/errors/validation_exception.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,44 @@ impl ValidationError {
230230
}
231231
}
232232

233+
// TODO: is_utf8_char_boundary, floor_char_boundary and ceil_char_boundary
234+
// with builtin methods once https://github.com/rust-lang/rust/issues/93743 is resolved
235+
// These are just copy pasted from the current implementation
236+
const fn is_utf8_char_boundary(value: u8) -> bool {
237+
// This is bit magic equivalent to: b < 128 || b >= 192
238+
(value as i8) >= -0x40
239+
}
240+
241+
fn floor_char_boundary(value: &str, index: usize) -> usize {
242+
if index >= value.len() {
243+
value.len()
244+
} else {
245+
let lower_bound = index.saturating_sub(3);
246+
let new_index = value.as_bytes()[lower_bound..=index]
247+
.iter()
248+
.rposition(|b| is_utf8_char_boundary(*b));
249+
250+
// SAFETY: we know that the character boundary will be within four bytes
251+
unsafe { lower_bound + new_index.unwrap_unchecked() }
252+
}
253+
}
254+
255+
pub fn ceil_char_boundary(value: &str, index: usize) -> usize {
256+
let upper_bound = Ord::min(index + 4, value.len());
257+
value.as_bytes()[index..upper_bound]
258+
.iter()
259+
.position(|b| is_utf8_char_boundary(*b))
260+
.map_or(upper_bound, |pos| pos + index)
261+
}
262+
233263
macro_rules! truncate_input_value {
234264
($out:expr, $value:expr) => {
235265
if $value.len() > 50 {
236-
dbg!($value.floor_char_boundary(25));
237-
dbg!($value.ceil_char_boundary($value.len() - 24));
238266
write!(
239267
$out,
240268
", input_value={}...{}",
241-
&$value[0..$value.floor_char_boundary(25)],
242-
&$value[$value.ceil_char_boundary($value.len() - 24)..]
269+
&$value[0..floor_char_boundary($value, 25)],
270+
&$value[ceil_char_boundary($value, $value.len() - 24)..]
243271
)?;
244272
} else {
245273
write!($out, ", input_value={}", $value)?;
@@ -383,7 +411,7 @@ impl PyLineError {
383411
if !hide_input {
384412
let input_value = self.input_value.as_ref(py);
385413
let input_str = safe_repr(input_value);
386-
truncate_input_value!(output, input_str);
414+
truncate_input_value!(output, &input_str);
387415

388416
if let Ok(type_) = input_value.get_type().name() {
389417
write!(output, ", input_type={type_}")?;

tests/test_misc.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import copy
2-
import os
32
import pickle
43
import re
5-
from unittest.mock import patch
64

75
import pytest
86
from typing_extensions import get_args
@@ -189,10 +187,9 @@ def test_unicode_error_input_repr() -> None:
189187
validator = SchemaValidator(schema)
190188

191189
danger_str = 'ÿ' * 1000
192-
with patch.dict(os.environ, {'PYDANTIC_ERRORS_OMIT_URL': '1'}):
193-
with pytest.raises(ValidationError) as exc_info:
194-
validator.validate_python(danger_str)
195-
assert (
196-
repr(exc_info.value)
197-
== "1 validation error for int\n Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='ÿÿÿÿÿÿÿÿÿÿÿÿ...ÿÿÿÿÿÿÿÿÿÿÿ', input_type=str]" # noqa: E501
198-
)
190+
expected = "1 validation error for int\n Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='ÿÿÿÿÿÿÿÿÿÿÿÿ...ÿÿÿÿÿÿÿÿÿÿÿ', input_type=str]" # noqa: E501
191+
with pytest.raises(ValidationError) as exc_info:
192+
validator.validate_python(danger_str)
193+
actual = repr(exc_info.value).split('For further information visit ')[0].strip()
194+
195+
assert expected == actual

0 commit comments

Comments
 (0)