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

davidcole1340 / ext-php-rs / 14501981872

16 Apr 2025 08:30PM UTC coverage: 14.129% (+0.7%) from 13.479%
14501981872

push

github

web-flow
style(clippy): apply pedantic rules

Refs: #418

41 of 345 new or added lines in 46 files covered. (11.88%)

48 existing lines in 25 files now uncovered.

553 of 3914 relevant lines covered (14.13%)

1.3 hits per line

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

0.0
/src/binary_slice.rs
1
//! Provides implementations for converting from Zend binary strings as slices,
2
//! commonly returned from functions such as [`pack`] and [`unpack`].
3
//!
4
//! [`pack`]: https://www.php.net/manual/en/function.pack.php
5
//! [`unpack`]: https://www.php.net/manual/en/function.unpack.php
6

7
use crate::ffi::zend_string;
8

9
use std::{ops::Deref, slice::from_raw_parts};
10

11
use crate::{convert::FromZval, flags::DataType, types::Zval};
12

13
/// Acts as a wrapper around `&[T]` where `T` implements [`PackSlice`].
14
/// Primarily used for passing read-only binary data into Rust functions.
15
#[derive(Debug)]
16
pub struct BinarySlice<'a, T>(&'a [T])
17
where
18
    T: PackSlice;
19

20
impl<'a, T> BinarySlice<'a, T>
21
where
22
    T: PackSlice,
23
{
24
    /// Creates a new binary slice wrapper from a slice of data.
25
    ///
26
    /// # Parameters
27
    ///
28
    /// * `data` - Slice to store inside the binary wrapper.
29
    pub fn new(data: &'a [T]) -> Self {
×
30
        Self(data)
×
31
    }
32
}
33

34
impl<'a, T> Deref for BinarySlice<'a, T>
35
where
36
    T: PackSlice,
37
{
38
    type Target = &'a [T];
39

40
    fn deref(&self) -> &Self::Target {
×
41
        &self.0
×
42
    }
43
}
44

45
impl<'a, T> FromZval<'a> for BinarySlice<'a, T>
46
where
47
    T: PackSlice,
48
{
49
    const TYPE: DataType = DataType::String;
50

51
    fn from_zval(zval: &'a Zval) -> Option<Self> {
×
52
        zval.binary_slice().map(BinarySlice)
×
53
    }
54
}
55

56
impl<'a, T> From<BinarySlice<'a, T>> for &'a [T]
57
where
58
    T: PackSlice,
59
{
60
    fn from(value: BinarySlice<'a, T>) -> Self {
×
61
        value.0
×
62
    }
63
}
64

65
impl<'a, T> From<&'a [T]> for BinarySlice<'a, T>
66
where
67
    T: PackSlice,
68
{
69
    fn from(value: &'a [T]) -> Self {
×
70
        Self::new(value)
×
71
    }
72
}
73

74
/// Used to expose a Zend binary string as a slice. Useful in conjunction with
75
/// the [`pack`] and [`unpack`] functions built-in to PHP.
76
///
77
/// # Safety
78
///
79
/// The types cannot be ensured between PHP and Rust, as the data is represented
80
/// as a string when crossing the language boundary. Exercise caution when using
81
/// these functions.
82
///
83
/// [`pack`]: https://www.php.net/manual/en/function.pack.php
84
/// [`unpack`]: https://www.php.net/manual/en/function.unpack.php
85
pub unsafe trait PackSlice: Clone {
86
    /// Creates a Rust slice from a given Zend binary string. Can be used to
87
    /// pass data from `pack` in PHP to Rust without encoding into another
88
    /// format. Note that the data *must* be all one type, as this
89
    /// implementation only unpacks one type.
90
    ///
91
    /// # Safety
92
    ///
93
    /// There is no way to tell if the data stored in the string is actually of
94
    /// the given type. The results of this function can also differ from
95
    /// platform-to-platform due to the different representation of some
96
    /// types on different platforms. Consult the [`pack`] function
97
    /// documentation for more details.
98
    ///
99
    /// # Parameters
100
    ///
101
    /// * `s` - The Zend string containing the binary data.
102
    ///
103
    /// [`pack`]: https://www.php.net/manual/en/function.pack.php
104
    fn unpack_into(s: &zend_string) -> &[Self];
105
}
106

107
/// Implements the [`PackSlice`] trait for a given type.
108
macro_rules! pack_slice_impl {
109
    ($t: ty) => {
110
        pack_slice_impl!($t, <$t>::BITS);
111
    };
112

113
    ($t: ty, $d: expr) => {
114
        unsafe impl PackSlice for $t {
115
            fn unpack_into(s: &zend_string) -> &[Self] {
×
116
                let bytes = ($d / 8) as usize;
×
117
                let len = (s.len as usize) / bytes;
×
118
                // TODO: alignment needs fixing?
NEW
119
                #[allow(clippy::cast_ptr_alignment)]
×
NEW
120
                let ptr = s.val.as_ptr().cast::<$t>();
×
UNCOV
121
                unsafe { from_raw_parts(ptr, len) }
×
122
            }
123
        }
124
    };
125
}
126

127
pack_slice_impl!(u8);
128
pack_slice_impl!(i8);
129

130
pack_slice_impl!(u16);
131
pack_slice_impl!(i16);
132

133
pack_slice_impl!(u32);
134
pack_slice_impl!(i32);
135

136
pack_slice_impl!(u64);
137
pack_slice_impl!(i64);
138

139
pack_slice_impl!(isize);
140
pack_slice_impl!(usize);
141

142
pack_slice_impl!(f32, 32);
143
pack_slice_impl!(f64, 64);
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

© 2025 Coveralls, Inc