1use crate::{
2 builtins::PyStr,
3 convert::{ToPyException, ToPyObject},
4 PyObjectRef, PyResult, VirtualMachine,
5};
6
7pub fn hash_iter<'a, I: IntoIterator<Item = &'a PyObjectRef>>(
8 iter: I,
9 vm: &VirtualMachine,
10) -> PyResult<rustpython_common::hash::PyHash> {
11 vm.state.hash_secret.hash_iter(iter, |obj| obj.hash(vm))
12}
13
14impl ToPyObject for std::convert::Infallible {
15 fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
16 match self {}
17 }
18}
19
20pub trait ToCString {
21 fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString>;
22}
23
24impl ToCString for &str {
25 fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString> {
26 std::ffi::CString::new(*self).map_err(|err| err.to_pyexception(vm))
27 }
28}
29
30impl ToCString for PyStr {
31 fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString> {
32 std::ffi::CString::new(self.as_ref()).map_err(|err| err.to_pyexception(vm))
33 }
34}
35
36pub(crate) fn collection_repr<'a, I>(
37 class_name: Option<&str>,
38 prefix: &str,
39 suffix: &str,
40 iter: I,
41 vm: &VirtualMachine,
42) -> PyResult<String>
43where
44 I: std::iter::Iterator<Item = &'a PyObjectRef>,
45{
46 let mut repr = String::new();
47 if let Some(name) = class_name {
48 repr.push_str(name);
49 repr.push('(');
50 }
51 repr.push_str(prefix);
52 {
53 let mut parts_iter = iter.map(|o| o.repr(vm));
54 repr.push_str(
55 parts_iter
56 .next()
57 .transpose()?
58 .expect("this is not called for empty collection")
59 .as_str(),
60 );
61 for part in parts_iter {
62 repr.push_str(", ");
63 repr.push_str(part?.as_str());
64 }
65 }
66 repr.push_str(suffix);
67 if class_name.is_some() {
68 repr.push(')');
69 }
70
71 Ok(repr)
72}