Skip to content

Commit 2f990df

Browse files
committed
Let c_void be a valid encoding in more places
1 parent ce6100c commit 2f990df

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

crates/objc2-encode/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## Unreleased - YYYY-MM-DD
88

9+
### Fixed
10+
* Allow the encoding of `*mut c_void` in a few places where they would not
11+
otherwise be equivalent.
12+
913

1014
## 2.0.0 - 2023-06-20
1115

crates/objc2-encode/src/encoding.rs

+21
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ impl Encoding {
203203
///
204204
/// See [`Encoding::equivalent_to`] for details about the meaning of
205205
/// "equivalence".
206+
///
207+
/// This differs from [`Encoding::equivalent_to`] in the following:
208+
/// - The encoding `Encoding::Pointer(&Encoding::Void)` (`*mut c_void`) is
209+
/// allowed where other types are expected.
206210
pub fn equivalent_to_str(&self, s: &str) -> bool {
207211
let mut parser = Parser::new(s);
208212

@@ -597,4 +601,21 @@ mod tests {
597601

598602
assert!(!enc.equivalent_to_box(&expected));
599603
}
604+
605+
#[test]
606+
fn pointer_to_void() {
607+
let v = Encoding::Pointer(&Encoding::Void);
608+
let s = Encoding::Pointer(&Encoding::Struct("abc", &[]));
609+
610+
assert!(v.equivalent_to(&s));
611+
assert!(s.equivalent_to(&v));
612+
assert!(v.equivalent_to_str("^{abc=}"));
613+
assert!(s.equivalent_to_str("^v"));
614+
615+
assert!(!Encoding::Atomic(&Encoding::Struct("abc", &[])).equivalent_to(&v));
616+
assert!(!Encoding::Atomic(&Encoding::Void).equivalent_to(&s));
617+
618+
assert!(!Encoding::Void.equivalent_to_str("{abc=}"));
619+
assert!(!Encoding::Struct("abc", &[]).equivalent_to_str("v"));
620+
}
600621
}

crates/objc2-encode/src/helper.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ impl NestingLevel {
1717
Self::Top
1818
}
1919

20+
pub(crate) const fn should_void_allow_non_void(self) -> bool {
21+
match self {
22+
Self::Top => false,
23+
Self::Bottom | Self::Within => true,
24+
}
25+
}
26+
2027
const fn bitfield(self) -> Self {
2128
// This is a bit irrelevant, since bitfields can only contain integral
2229
// types
@@ -80,9 +87,15 @@ pub(crate) fn compare_encodings<E1: EncodingType, E2: EncodingType>(
8087
level2
8188
};
8289

83-
// TODO: Are level1 and level2 ever be different?
90+
// TODO: Are level1 and level2 ever different?
8491

8592
match (enc1.helper(level1), enc2.helper(level2)) {
93+
(Primitive(crate::helper::Primitive::Void), _) if level1.should_void_allow_non_void() => {
94+
true
95+
}
96+
(_, Primitive(crate::helper::Primitive::Void)) if level2.should_void_allow_non_void() => {
97+
true
98+
}
8699
(Primitive(p1), Primitive(p2)) => p1 == p2,
87100
(
88101
BitField(size1, Some((offset1, type1)), level1),

crates/objc2-encode/src/parse.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use alloc::string::{String, ToString};
55
use alloc::vec::Vec;
66
use core::fmt;
77

8-
use crate::helper::{ContainerKind, Helper, NestingLevel};
8+
use crate::helper::{ContainerKind, Helper, NestingLevel, Primitive};
99
use crate::{Encoding, EncodingBox};
1010

1111
/// Check whether a struct or union name is a valid identifier
@@ -251,7 +251,20 @@ impl Parser<'_> {
251251

252252
pub(crate) fn expect_encoding(&mut self, enc: &Encoding, level: NestingLevel) -> Option<()> {
253253
let helper = Helper::new(enc, level);
254+
if level.should_void_allow_non_void() && self.expect_byte(b'v').is_some() {
255+
return Some(());
256+
}
254257
match helper {
258+
Helper::Primitive(Primitive::Void) if level.should_void_allow_non_void() => {
259+
if self.expect_byte(b'v').is_some() {
260+
Some(())
261+
} else {
262+
match self.parse_encoding() {
263+
Ok(_) => Some(()),
264+
Err(_) => None,
265+
}
266+
}
267+
}
255268
Helper::Primitive(primitive) => self.expect_str(primitive.to_str()),
256269
Helper::BitField(size, Some((offset, t)), level) => {
257270
self.expect_byte(b'b')?;

0 commit comments

Comments
 (0)