Skip to content

Commit 250cafa

Browse files
committed
add to private set
1 parent 9d8af8a commit 250cafa

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

src/input/return_enums.rs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
use std::borrow::Cow;
22
use std::slice::Iter as SliceIter;
33

4-
use pyo3::intern;
54
use pyo3::prelude::*;
65
use pyo3::types::iter::PyDictIterator;
76
use pyo3::types::{PyBytes, PyDict, PyFrozenSet, PyIterator, PyList, PyMapping, PySet, PyString, PyTuple};
7+
use pyo3::{ffi, intern, AsPyPointer, PyNativeType};
88

99
#[cfg(not(PyPy))]
1010
use pyo3::types::PyFunction;
1111
#[cfg(not(PyPy))]
1212
use pyo3::PyTypeInfo;
1313

1414
use crate::errors::{py_err_string, ErrorType, InputValue, ValError, ValLineError, ValResult};
15+
use crate::input::py_error_on_minusone;
1516
use crate::recursion_guard::RecursionGuard;
1617
use crate::validators::{CombinedValidator, Extra, Validator};
1718

@@ -131,9 +132,41 @@ fn validate_iter_to_vec<'a, 's>(
131132
}
132133
}
133134

135+
pub trait BuildSet {
136+
fn build_add(&self, item: PyObject) -> PyResult<()>;
137+
138+
fn build_len(&self) -> usize;
139+
}
140+
141+
impl BuildSet for &PySet {
142+
fn build_add(&self, item: PyObject) -> PyResult<()> {
143+
self.add(item)
144+
}
145+
146+
fn build_len(&self) -> usize {
147+
self.len()
148+
}
149+
}
150+
151+
impl BuildSet for &PyFrozenSet {
152+
fn build_add(&self, item: PyObject) -> PyResult<()> {
153+
unsafe {
154+
py_error_on_minusone(
155+
self.py(),
156+
ffi::PySet_Add(self.as_ptr(), item.to_object(self.py()).as_ptr()),
157+
)
158+
}
159+
}
160+
161+
fn build_len(&self) -> usize {
162+
self.len()
163+
}
164+
}
165+
134166
#[allow(clippy::too_many_arguments)]
135167
fn validate_iter_to_set<'a, 's>(
136168
py: Python<'a>,
169+
set: impl BuildSet,
137170
iter: impl Iterator<Item = PyResult<&'a (impl Input<'a> + 'a)>>,
138171
input: &'a (impl Input<'a> + 'a),
139172
field_type: &'static str,
@@ -142,16 +175,15 @@ fn validate_iter_to_set<'a, 's>(
142175
extra: &Extra,
143176
definitions: &'a [CombinedValidator],
144177
recursion_guard: &'s mut RecursionGuard,
145-
) -> ValResult<'a, &'a PySet> {
146-
let set = PySet::empty(py)?;
178+
) -> ValResult<'a, ()> {
147179
let mut errors: Vec<ValLineError> = Vec::new();
148180
for (index, item_result) in iter.enumerate() {
149181
let item = item_result.map_err(|e| any_next_error!(py, e, input, index))?;
150182
match validator.validate(py, item, extra, definitions, recursion_guard) {
151183
Ok(item) => {
152-
set.add(item)?;
184+
set.build_add(item)?;
153185
if let Some(max_length) = max_length {
154-
let actual_length = set.len();
186+
let actual_length = set.build_len();
155187
if actual_length > max_length {
156188
return Err(ValError::new(
157189
ErrorType::TooLong {
@@ -173,7 +205,7 @@ fn validate_iter_to_set<'a, 's>(
173205
}
174206

175207
if errors.is_empty() {
176-
Ok(set)
208+
Ok(())
177209
} else {
178210
Err(ValError::LineErrors(errors))
179211
}
@@ -252,18 +284,20 @@ impl<'a> GenericCollection<'a> {
252284
pub fn validate_to_set<'s>(
253285
&'s self,
254286
py: Python<'a>,
287+
set: impl BuildSet,
255288
input: &'a impl Input<'a>,
256289
max_length: Option<usize>,
257290
field_type: &'static str,
258291
validator: &'s CombinedValidator,
259292
extra: &Extra,
260293
definitions: &'a [CombinedValidator],
261294
recursion_guard: &'s mut RecursionGuard,
262-
) -> ValResult<'a, &'a PySet> {
295+
) -> ValResult<'a, ()> {
263296
macro_rules! validate_set {
264297
($iter:expr) => {
265298
validate_iter_to_set(
266299
py,
300+
set,
267301
$iter,
268302
input,
269303
field_type,

src/validators/frozenset.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ impl Validator for FrozenSetValidator {
3434
recursion_guard: &'s mut RecursionGuard,
3535
) -> ValResult<'data, PyObject> {
3636
let collection = input.validate_frozenset(extra.strict.unwrap_or(self.strict))?;
37-
38-
let set = collection.validate_to_set(
37+
let f_set = PyFrozenSet::empty(py)?;
38+
collection.validate_to_set(
3939
py,
40+
f_set,
4041
input,
4142
self.max_length,
4243
"Frozenset",
@@ -45,8 +46,7 @@ impl Validator for FrozenSetValidator {
4546
definitions,
4647
recursion_guard,
4748
)?;
48-
min_length_check!(input, "Frozenset", self.min_length, set);
49-
let f_set = PyFrozenSet::new(py, set)?;
49+
min_length_check!(input, "Frozenset", self.min_length, f_set);
5050
Ok(f_set.into_py(py))
5151
}
5252

src/validators/set.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use pyo3::prelude::*;
2-
use pyo3::types::PyDict;
2+
use pyo3::types::{PyDict, PySet};
33

44
use crate::build_tools::SchemaDict;
55
use crate::errors::ValResult;
@@ -65,8 +65,10 @@ impl Validator for SetValidator {
6565
recursion_guard: &'s mut RecursionGuard,
6666
) -> ValResult<'data, PyObject> {
6767
let collection = input.validate_set(extra.strict.unwrap_or(self.strict))?;
68-
let set = collection.validate_to_set(
68+
let set = PySet::empty(py)?;
69+
collection.validate_to_set(
6970
py,
71+
set,
7072
input,
7173
self.max_length,
7274
"Set",

0 commit comments

Comments
 (0)