• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

extphprs / ext-php-rs / 20173570354

12 Dec 2025 04:44PM UTC coverage: 35.19% (-0.04%) from 35.229%
20173570354

Pull #598

github

web-flow
Merge d36bd8d87 into ea4577563
Pull Request #598: feat(types): Argument coercion into HashSet/BTreeSet #493

15 of 42 new or added lines in 3 files covered. (35.71%)

2 existing lines in 1 file now uncovered.

1611 of 4578 relevant lines covered (35.19%)

8.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.25
/src/types/array/conversions/hash_set.rs
1
use super::super::ZendHashTable;
2
use crate::{
3
    boxed::ZBox,
4
    convert::{FromZval, IntoZval},
5
    error::{Error, Result},
6
    flags::DataType,
7
    types::Zval,
8
};
9
use std::collections::HashSet;
10
use std::convert::TryFrom;
11
use std::hash::{BuildHasher, Hash};
12

13
impl<'a, V, H> TryFrom<&'a ZendHashTable> for HashSet<V, H>
14
where
15
    V: FromZval<'a> + Eq + Hash,
16
    H: BuildHasher + Default,
17
{
18
    type Error = Error;
19

NEW
20
    fn try_from(value: &'a ZendHashTable) -> Result<Self> {
×
NEW
21
        let mut set = Self::with_capacity_and_hasher(value.len(), H::default());
×
22

NEW
23
        for (_key, val) in value {
×
NEW
24
            set.insert(V::from_zval(val).ok_or_else(|| Error::ZvalConversion(val.get_type()))?);
×
25
        }
26

NEW
27
        Ok(set)
×
28
    }
29
}
30

31
impl<V, H> TryFrom<HashSet<V, H>> for ZBox<ZendHashTable>
32
where
33
    V: IntoZval,
34
    H: BuildHasher,
35
{
36
    type Error = Error;
37

38
    fn try_from(value: HashSet<V, H>) -> Result<Self> {
1✔
39
        let mut ht = ZendHashTable::with_capacity(
40
            value.len().try_into().map_err(|_| Error::IntegerOverflow)?,
4✔
41
        );
42

43
        for (k, v) in value.into_iter().enumerate() {
5✔
44
            ht.insert(k, v)?;
3✔
45
        }
46

47
        Ok(ht)
1✔
48
    }
49
}
50

51
impl<'a, V, H> FromZval<'a> for HashSet<V, H>
52
where
53
    V: FromZval<'a> + Eq + Hash,
54
    H: BuildHasher + Default,
55
{
56
    const TYPE: DataType = DataType::Array;
57

NEW
58
    fn from_zval(zval: &'a Zval) -> Option<Self> {
×
NEW
59
        zval.array().and_then(|arr| arr.try_into().ok())
×
60
    }
61
}
62

63
impl<V, H> IntoZval for HashSet<V, H>
64
where
65
    V: IntoZval,
66
    H: BuildHasher,
67
{
68
    const TYPE: DataType = DataType::Array;
69
    const NULLABLE: bool = false;
70

NEW
71
    fn set_zval(self, zv: &mut Zval, _: bool) -> Result<()> {
×
NEW
72
        let arr = self.try_into()?;
×
NEW
73
        zv.set_hashtable(arr);
×
NEW
74
        Ok(())
×
75
    }
76
}
77

78
#[cfg(test)]
79
#[cfg(feature = "embed")]
80
#[allow(clippy::unwrap_used)]
81
mod tests {
82
    use std::collections::HashSet;
83

84
    use crate::boxed::ZBox;
85
    use crate::embed::Embed;
86
    use crate::types::ZendHashTable;
87

88
    #[test]
89
    fn test_hash_table_try_from_hash_set() {
90
        Embed::run(|| {
91
            let mut set = HashSet::new();
92
            set.insert("one");
93
            let ht: ZBox<ZendHashTable> = set.try_into().unwrap();
94
            assert_eq!(ht.len(), 1);
95
            assert!(ht.get(0).is_some());
96
        });
97
    }
98
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc