Skip to content

Commit 528cc51

Browse files
committed
Pass compiled.
1 parent 895993e commit 528cc51

File tree

14 files changed

+149
-161
lines changed

14 files changed

+149
-161
lines changed

examples/http-client/src/response.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// See the Mulan PSL v2 for more details.
1010

1111
use crate::{errors::HttpClientError, utils::replace_and_get};
12-
use indexmap::map::IndexMap;
1312
use phper::{
1413
arrays::{InsertKey, ZArray},
1514
classes::{DynamicClass, Visibility},

examples/http-server/src/server.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,18 @@ use hyper::{
2020
use phper::{
2121
alloc::EBox,
2222
classes::{ClassEntry, DynamicClass, StatelessClassEntry, Visibility},
23-
errors::{Error::Throw, MapMustBeTypeError},
23+
errors::Error::Throw,
2424
functions::Argument,
25-
types::TypeInfo,
2625
values::ZVal,
2726
};
2827
use std::{
29-
cell::RefCell,
3028
convert::Infallible,
3129
mem::replace,
3230
net::SocketAddr,
3331
ptr::null_mut,
34-
sync::{
35-
atomic::{AtomicPtr, Ordering},
36-
Arc,
37-
},
32+
sync::atomic::{AtomicPtr, Ordering},
3833
};
39-
use tokio::{runtime::Handle, sync::Mutex};
34+
use tokio::runtime::Handle;
4035

4136
const HTTP_SERVER_CLASS_NAME: &str = "HttpServer\\HttpServer";
4237

@@ -51,12 +46,8 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
5146
"__construct",
5247
Visibility::Public,
5348
|this, arguments| {
54-
let host = arguments[0]
55-
.as_z_str()
56-
.map_must_be_type_error(TypeInfo::string(), arguments[0].get_type_info())?;
57-
let port = arguments[1]
58-
.as_long()
59-
.map_must_be_type_error(TypeInfo::string(), arguments[0].get_type_info())?;
49+
let host = arguments[0].expect_z_str()?;
50+
let port = arguments[1].expect_long()?;
6051
this.set_property("host", host);
6152
this.set_property("port", port);
6253
let addr = format!("{}:{}", host.to_str()?, port).parse::<SocketAddr>()?;

phper-alloc/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#![warn(rust_2018_idioms, clippy::dbg_macro, clippy::print_stdout)]
1212
#![doc = include_str!("../README.md")]
1313

14+
#[macro_use]
15+
mod macros;
16+
1417
use phper_sys::*;
1518
use std::{
1619
convert::TryInto,

phper-alloc/src/macros.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// Wrapper of `EBox::new`.
2+
///
3+
/// # Examples
4+
///
5+
/// ```no_test
6+
/// let _ = ebox!(1);
7+
/// ```
8+
#[macro_export]
9+
macro_rules! ebox {
10+
($arg:tt) => {{
11+
$crate::EBox::new($arg)
12+
}};
13+
}

phper/src/errors.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ pub enum Error {
105105
#[error(transparent)]
106106
#[throwable(transparent)]
107107
NotRefCountedType(#[from] NotRefCountedTypeError),
108+
109+
#[error(transparent)]
110+
#[throwable(transparent)]
111+
ExpectType(#[from] ExpectTypeError),
108112
}
109113

110114
impl Error {
@@ -122,6 +126,14 @@ pub struct TypeError {
122126
message: String,
123127
}
124128

129+
#[derive(Debug, thiserror::Error, crate::Throwable, Constructor)]
130+
#[error("type error: must be of type {expect_type}, {actual_type} given")]
131+
#[throwable_class("TypeError")]
132+
pub struct ExpectTypeError {
133+
expect_type: TypeInfo,
134+
actual_type: TypeInfo,
135+
}
136+
125137
#[derive(Debug, thiserror::Error, crate::Throwable, Constructor)]
126138
#[error("Class '{class_name}' not found")]
127139
#[throwable_class("Error")]
@@ -179,17 +191,3 @@ pub struct InitializeObjectError {
179191
#[error("the type is not refcounted")]
180192
#[throwable_class("TypeError")]
181193
pub struct NotRefCountedTypeError;
182-
183-
pub trait MapMustBeTypeError<T> {
184-
fn map_must_be_type_error(self, expect_type: TypeInfo, actual_type: TypeInfo) -> Result<T>;
185-
}
186-
187-
impl<T> MapMustBeTypeError<T> for Option<T> {
188-
fn map_must_be_type_error(self, expect_type: TypeInfo, actual_type: TypeInfo) -> Result<T> {
189-
self.ok_or_else(|| {
190-
Error::Type(TypeError {
191-
message: format!("must be of type {}, {} given", expect_type, actual_type),
192-
})
193-
})
194-
}
195-
}

phper/src/strings.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,18 @@ impl Borrow<ZStr> for ZString {
152152
}
153153
}
154154

155+
impl AsRef<[u8]> for ZString {
156+
fn as_ref(&self) -> &[u8] {
157+
self.to_bytes()
158+
}
159+
}
160+
161+
impl<Rhs: AsRef<[u8]>> PartialEq<Rhs> for ZString {
162+
fn eq(&self, other: &Rhs) -> bool {
163+
self.as_ref() == other.as_ref()
164+
}
165+
}
166+
155167
impl Drop for ZString {
156168
fn drop(&mut self) {
157169
unsafe {

phper/src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl TypeInfo {
2626
pub const DOUBLE: TypeInfo = TypeInfo::from_raw(IS_DOUBLE);
2727
pub const LONG: TypeInfo = TypeInfo::from_raw(IS_LONG);
2828
pub const NULL: TypeInfo = TypeInfo::from_raw(IS_NULL);
29+
pub const OBJECT: TypeInfo = TypeInfo::from_raw(IS_OBJECT);
2930
pub const STRING: TypeInfo = TypeInfo::from_raw(IS_STRING);
3031
pub const UNDEF: TypeInfo = TypeInfo::from_raw(IS_UNDEF);
3132
}

phper/src/values.rs

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
alloc::EBox,
1515
arrays::{ZArr, ZArray},
1616
classes::ClassEntry,
17-
errors::{NotRefCountedTypeError, Throwable, TypeError},
17+
errors::{ExpectTypeError, NotRefCountedTypeError, Throwable, TypeError},
1818
functions::{call_internal, ZendFunction},
1919
objects::{Object, StatelessObject},
2020
resources::ZRes,
@@ -166,29 +166,41 @@ impl ZVal {
166166
}
167167

168168
pub fn as_null(&self) -> Option<()> {
169+
self.expect_null().ok()
170+
}
171+
172+
pub fn expect_null(&self) -> crate::Result<()> {
169173
if self.get_type_info().is_null() {
170-
Some(())
174+
Ok(())
171175
} else {
172-
None
176+
Err(ExpectTypeError::new(TypeInfo::NULL, self.get_type_info()).into())
173177
}
174178
}
175179

176180
pub fn as_bool(&self) -> Option<bool> {
181+
self.expect_bool().ok()
182+
}
183+
184+
pub fn expect_bool(&self) -> crate::Result<bool> {
177185
let t = self.get_type_info();
178186
if t.is_true() {
179-
Some(true)
187+
Ok(true)
180188
} else if t.is_false() {
181-
Some(false)
189+
Ok(false)
182190
} else {
183-
None
191+
Err(ExpectTypeError::new(TypeInfo::BOOL, self.get_type_info()).into())
184192
}
185193
}
186194

187195
pub fn as_long(&self) -> Option<i64> {
196+
self.expect_long().ok()
197+
}
198+
199+
pub fn expect_long(&self) -> crate::Result<i64> {
188200
if self.get_type_info().is_long() {
189-
unsafe { Some(phper_z_lval_p(self.as_ptr())) }
201+
unsafe { Ok(phper_z_lval_p(self.as_ptr())) }
190202
} else {
191-
None
203+
Err(ExpectTypeError::new(TypeInfo::LONG, self.get_type_info()).into())
192204
}
193205
}
194206

@@ -198,18 +210,38 @@ impl ZVal {
198210
}
199211

200212
pub fn as_double(&self) -> Option<f64> {
213+
self.expect_double().ok()
214+
}
215+
216+
pub fn expect_double(&self) -> crate::Result<f64> {
201217
if self.get_type_info().is_double() {
202-
unsafe { Some(phper_z_dval_p(self.as_ptr())) }
218+
unsafe { Ok(phper_z_dval_p(self.as_ptr())) }
203219
} else {
204-
None
220+
Err(ExpectTypeError::new(TypeInfo::DOUBLE, self.get_type_info()).into())
205221
}
206222
}
207223

208224
pub fn as_z_str(&self) -> Option<&ZStr> {
225+
self.expect_z_str().ok()
226+
}
227+
228+
pub fn expect_z_str(&self) -> crate::Result<&ZStr> {
209229
if self.get_type_info().is_string() {
210-
unsafe { Some(ZStr::from_mut_ptr(phper_z_str_p(self.as_ptr()))) }
230+
unsafe { Ok(ZStr::from_mut_ptr(phper_z_str_p(self.as_ptr()))) }
211231
} else {
212-
None
232+
Err(ExpectTypeError::new(TypeInfo::STRING, self.get_type_info()).into())
233+
}
234+
}
235+
236+
pub fn as_mut_z_str(&mut self) -> Option<&mut ZStr> {
237+
self.expect_mut_z_str().ok()
238+
}
239+
240+
pub fn expect_mut_z_str(&mut self) -> crate::Result<&mut ZStr> {
241+
if self.get_type_info().is_string() {
242+
unsafe { Ok(ZStr::from_mut_ptr(phper_z_str_p(self.as_mut_ptr()))) }
243+
} else {
244+
Err(ExpectTypeError::new(TypeInfo::STRING, self.get_type_info()).into())
213245
}
214246
}
215247

@@ -222,40 +254,56 @@ impl ZVal {
222254
}
223255

224256
pub fn as_z_arr(&self) -> Option<&ZArr> {
257+
self.expect_z_arr().ok()
258+
}
259+
260+
pub fn expect_z_arr(&self) -> crate::Result<&ZArr> {
225261
if self.get_type_info().is_array() {
226-
unsafe { Some(ZArr::from_mut_ptr(phper_z_arr_p(self.as_ptr()))) }
262+
unsafe { Ok(ZArr::from_mut_ptr(phper_z_arr_p(self.as_ptr()))) }
227263
} else {
228-
None
264+
Err(ExpectTypeError::new(TypeInfo::ARRAY, self.get_type_info()).into())
229265
}
230266
}
231267

232268
pub fn as_mut_z_arr(&mut self) -> Option<&mut ZArr> {
269+
self.expect_mut_z_arr().ok()
270+
}
271+
272+
pub fn expect_mut_z_arr(&mut self) -> crate::Result<&mut ZArr> {
233273
if self.get_type_info().is_array() {
234-
unsafe { Some(ZArr::from_mut_ptr(phper_z_arr_p(self.as_ptr()))) }
274+
unsafe { Ok(ZArr::from_mut_ptr(phper_z_arr_p(self.as_ptr()))) }
235275
} else {
236-
None
276+
Err(ExpectTypeError::new(TypeInfo::ARRAY, self.get_type_info()).into())
237277
}
238278
}
239279

240-
pub fn as_object(&self) -> crate::Result<&Object<()>> {
280+
pub fn as_object(&self) -> Option<&Object<()>> {
281+
self.expect_object().ok()
282+
}
283+
284+
pub fn expect_object(&self) -> crate::Result<&Object<()>> {
241285
if self.get_type_info().is_object() {
242286
unsafe {
243287
let ptr = self.inner.value.obj;
244288
Ok(Object::from_mut_ptr(ptr))
245289
}
246290
} else {
247-
Err(self.must_be_type_error("object"))
291+
Err(ExpectTypeError::new(TypeInfo::OBJECT, self.get_type_info()).into())
248292
}
249293
}
250294

251-
pub fn as_mut_object(&mut self) -> crate::Result<&mut Object<()>> {
295+
pub fn as_mut_object(&mut self) -> Option<&mut Object<()>> {
296+
self.expect_mut_object().ok()
297+
}
298+
299+
pub fn expect_mut_object(&mut self) -> crate::Result<&mut Object<()>> {
252300
if self.get_type_info().is_object() {
253301
unsafe {
254302
let ptr = self.inner.value.obj;
255303
Ok(Object::from_mut_ptr(ptr))
256304
}
257305
} else {
258-
Err(self.must_be_type_error("object"))
306+
Err(ExpectTypeError::new(TypeInfo::OBJECT, self.get_type_info()).into())
259307
}
260308
}
261309

tests/integration/src/arguments.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// See the Mulan PSL v2 for more details.
1010

1111
use phper::{
12-
alloc::EBox, arrays::ZArray, errors::MapMustBeTypeError, functions::Argument, modules::Module,
13-
objects::Object, types::TypeInfo, values::ZVal,
12+
alloc::EBox, arrays::ZArray, functions::Argument, modules::Module, objects::Object,
13+
values::ZVal,
1414
};
1515

1616
pub fn integrate(module: &mut Module) {
@@ -27,9 +27,7 @@ fn integrate_arguments(module: &mut Module) {
2727
module.add_function(
2828
"integrate_arguments_long",
2929
|arguments: &mut [ZVal]| -> phper::Result<i64> {
30-
let a = arguments[0]
31-
.as_long()
32-
.map_must_be_type_error(TypeInfo::LONG, arguments[0].get_type_info())?;
30+
let a = arguments[0].expect_long()?;
3331
let b = arguments[1].as_long_value();
3432
Ok(a + b)
3533
},
@@ -45,10 +43,7 @@ fn integrate_arguments(module: &mut Module) {
4543
module.add_function(
4644
"integrate_arguments_string",
4745
|arguments: &mut [ZVal]| -> phper::Result<String> {
48-
let a = arguments[0]
49-
.as_z_str()
50-
.map_must_be_type_error(TypeInfo::STRING, arguments[0].get_type_info())?
51-
.to_str()?;
46+
let a = arguments[0].expect_z_str()?.to_str()?;
5247
let b = arguments[1].as_string_value()?;
5348
Ok(format!("{}, {}", a, b))
5449
},
@@ -58,9 +53,7 @@ fn integrate_arguments(module: &mut Module) {
5853
module.add_function(
5954
"integrate_arguments_array",
6055
|arguments: &mut [ZVal]| -> phper::Result<ZArray> {
61-
let a = arguments[0]
62-
.as_z_arr()
63-
.map_must_be_type_error(TypeInfo::ARRAY, arguments[0].get_type_info())?;
56+
let a = arguments[0].expect_z_arr()?;
6457
let mut b = a.to_owned();
6558
b.insert("a", ZVal::from(1));
6659
b.insert("foo", ZVal::from("bar"));
@@ -72,7 +65,7 @@ fn integrate_arguments(module: &mut Module) {
7265
module.add_function(
7366
"integrate_arguments_object",
7467
|arguments: &mut [ZVal]| -> phper::Result<EBox<Object<()>>> {
75-
let a = arguments[0].as_object()?;
68+
let a = arguments[0].expect_object()?;
7669
let mut a = a.clone_obj();
7770
a.set_property("foo", ZVal::from("bar"));
7871
Ok(a)
@@ -83,16 +76,10 @@ fn integrate_arguments(module: &mut Module) {
8376
module.add_function(
8477
"integrate_arguments_optional",
8578
|arguments: &mut [ZVal]| -> phper::Result<String> {
86-
let a = arguments[0]
87-
.as_z_str()
88-
.map_must_be_type_error(TypeInfo::STRING, arguments[0].get_type_info())?
89-
.to_str()?;
79+
let a = arguments[0].expect_z_str()?.to_str()?;
9080
let b = arguments
9181
.get(1)
92-
.map(|b| {
93-
b.as_bool()
94-
.map_must_be_type_error(TypeInfo::BOOL, b.get_type_info())
95-
})
82+
.map(|b| b.expect_bool())
9683
.transpose()?
9784
.unwrap_or_default();
9885
Ok(format!("{}: {}", a, b))

tests/integration/src/arrays.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn integrate(module: &mut Module) {
7272
assert_eq!(arr.get(0).unwrap().as_long().unwrap(), 0);
7373
assert_eq!(arr.get(1).unwrap().as_long().unwrap(), 1);
7474

75-
let obj: &mut Object<()> = a.get_mut("obj").unwrap().as_mut_object()?;
75+
let obj: &mut Object<()> = a.get_mut("obj").unwrap().expect_mut_object()?;
7676
let val = obj.get_property("foo");
7777
assert_eq!(val.as_z_str().unwrap().to_str().unwrap(), "bar");
7878

0 commit comments

Comments
 (0)