From afa927539f57989c3d76f276054f37cd67e0ba06 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Thu, 13 Mar 2025 18:59:04 +0100 Subject: [PATCH 1/2] docs(cli): enforce docs for cli Refs: #392 --- crates/cli/Cargo.toml | 3 +++ crates/cli/src/lib.rs | 1 + crates/cli/src/main.rs | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 43da948b1c..055cfe5590 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -19,3 +19,6 @@ dialoguer = "0.11" libloading = "0.8" cargo_metadata = "0.15" semver = "1.0" + +[lints.rust] +missing_docs = "warn" diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 86b8692544..36cac33b34 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -26,6 +26,7 @@ macro_rules! stub_symbols { }; (@INTERNAL; $s: ident) => { #[allow(non_upper_case_globals)] + #[allow(missing_docs)] #[no_mangle] pub static mut $s: *mut () = ::std::ptr::null_mut(); }; diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 75c700ef77..0bc9be0af2 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,4 +1,9 @@ -// Mock macro for the `allowed_bindings.rs` script. +//! # `cargo-php` CLI +//! +//! Installs extensions and generates stub files for PHP extensions generated +//! with `ext-php-rs`. Use `cargo php --help` for more information. + +/// Mock macro for the `allowed_bindings.rs` script. #[cfg(not(windows))] macro_rules! bind { ($($s: ident),*) => { From 4fb718ff6e5583db4ff27fe5e55cf63ce8c6c211 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Thu, 13 Mar 2025 20:13:45 +0100 Subject: [PATCH 2/2] docs: enforce doc comments for `ext-php-rs` Refs: #392 --- Cargo.toml | 3 + src/constant.rs | 6 +- src/describe/abi.rs | 2 + src/flags.rs | 134 ++++++++++++++++++++++++++++++++++++++ src/props.rs | 13 ++-- src/types/array.rs | 4 +- src/types/class_object.rs | 2 + src/types/iterable.rs | 2 + src/types/object.rs | 6 ++ src/types/zval.rs | 1 + src/zend/class.rs | 1 + src/zend/function.rs | 5 ++ src/zend/globals.rs | 31 ++++++++- src/zend/ini_entry_def.rs | 1 + src/zend/linked_list.rs | 2 + src/zend/streams.rs | 18 +++++ 16 files changed, 218 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 96b44adcdb..56cd55125a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,9 @@ members = [ [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docs"] +[lints.rust] +missing_docs = "warn" + [[example]] name = "hello_world" crate-type = ["cdylib"] diff --git a/src/constant.rs b/src/constant.rs index 983811d6ff..7a05774484 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -40,11 +40,7 @@ pub trait IntoConst: Debug { /// } /// ``` fn register_constant(&self, name: &str, module_number: i32) -> Result<()> { - self.register_constant_flags( - name, - module_number, - GlobalConstantFlags::CaseSensitive | GlobalConstantFlags::Persistent, - ) + self.register_constant_flags(name, module_number, GlobalConstantFlags::Persistent) } /// Registers a global module constant in PHP, with the value as the content diff --git a/src/describe/abi.rs b/src/describe/abi.rs index e0d9dde50b..4f2da62aad 100644 --- a/src/describe/abi.rs +++ b/src/describe/abi.rs @@ -129,7 +129,9 @@ impl Display for RString { /// An ABI-stable [`Option`][std::option::Option]. #[repr(C, u8)] pub enum Option { + /// [`Option::Some`][std::option::Option::Some] variant. Some(T), + /// [`Option::None`][std::option::Option::None] variant. None, } diff --git a/src/flags.rs b/src/flags.rs index 7eadd4bd7d..2e50663839 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -34,32 +34,57 @@ bitflags! { /// Flags used for setting the type of Zval. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct ZvalTypeFlags: u32 { + /// Undefined const Undef = IS_UNDEF; + /// Null const Null = IS_NULL; + /// `false` const False = IS_FALSE; + /// `true` const True = IS_TRUE; + /// Integer const Long = IS_LONG; + /// Floating point number const Double = IS_DOUBLE; + /// String const String = IS_STRING; + /// Array const Array = IS_ARRAY; + /// Object const Object = IS_OBJECT; + /// Resource const Resource = IS_RESOURCE; + /// Reference const Reference = IS_REFERENCE; + /// Callable const Callable = IS_CALLABLE; + /// Constant expression const ConstantExpression = IS_CONSTANT_AST; + /// Void const Void = IS_VOID; + /// Pointer const Ptr = IS_PTR; + /// Iterable const Iterable = IS_ITERABLE; + /// Interned string extended const InternedStringEx = Self::String.bits(); + /// String extended const StringEx = Self::String.bits() | Self::RefCounted.bits(); + /// Array extended const ArrayEx = Self::Array.bits() | Self::RefCounted.bits() | Self::Collectable.bits(); + /// Object extended const ObjectEx = Self::Object.bits() | Self::RefCounted.bits() | Self::Collectable.bits(); + /// Resource extended const ResourceEx = Self::Resource.bits() | Self::RefCounted.bits(); + /// Reference extended const ReferenceEx = Self::Reference.bits() | Self::RefCounted.bits(); + /// Constant ast extended const ConstantAstEx = Self::ConstantExpression.bits() | Self::RefCounted.bits(); + /// Reference counted const RefCounted = (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + /// Collectable const Collectable = (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT); } } @@ -68,29 +93,52 @@ bitflags! { /// Flags for building classes. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct ClassFlags: u32 { + /// Final class or method const Final = ZEND_ACC_FINAL; + /// Abstract method const Abstract = ZEND_ACC_ABSTRACT; + /// Immutable `op_array` and class_entries + /// (implemented only for lazy loading of `op_array`s) const Immutable = ZEND_ACC_IMMUTABLE; + /// Function has typed arguments / class has typed props const HasTypeHints = ZEND_ACC_HAS_TYPE_HINTS; + /// Top-level class or function declaration const TopLevel = ZEND_ACC_TOP_LEVEL; + /// op_array or class is preloaded const Preloaded = ZEND_ACC_PRELOADED; + /// Class entry is an interface const Interface = ZEND_ACC_INTERFACE; + /// Class entry is a trait const Trait = ZEND_ACC_TRAIT; + /// Anonymous class const AnonymousClass = ZEND_ACC_ANON_CLASS; + /// Class linked with parent, interfaces and traits const Linked = ZEND_ACC_LINKED; + /// Class is abstract, since it is set by any abstract method const ImplicitAbstractClass = ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; + /// Class has magic methods `__get`/`__set`/`__unset`/`__isset` that use guards const UseGuards = ZEND_ACC_USE_GUARDS; + + /// Class constants updated const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED; + /// Objects of this class may not have dynamic properties const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES; + /// User class has methods with static variables const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS; + /// Children must reuse parent `get_iterator()` #[cfg(not(php82))] const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR; + /// Parent class is resolved (CE) const ResolvedParent = ZEND_ACC_RESOLVED_PARENT; + /// Interfaces are resolved (CE) const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES; + /// Class has unresolved variance obligations const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE; + /// Class is linked apart from variance obligations const NearlyLinked = ZEND_ACC_NEARLY_LINKED; + /// Class cannot be serialized or unserialized #[cfg(php81)] const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE; } @@ -100,34 +148,67 @@ bitflags! { /// Flags for building methods. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct MethodFlags: u32 { + /// Visibility public const Public = ZEND_ACC_PUBLIC; + /// Visibility protected const Protected = ZEND_ACC_PROTECTED; + /// Visibility private const Private = ZEND_ACC_PRIVATE; + /// Method or property overrides private one const Changed = ZEND_ACC_CHANGED; + /// Static method const Static = ZEND_ACC_STATIC; + /// Final method const Final = ZEND_ACC_FINAL; + /// Abstract method const Abstract = ZEND_ACC_ABSTRACT; + /// Immutable `op_array` and class_entries + /// (implemented only for lazy loading of op_arrays) const Immutable = ZEND_ACC_IMMUTABLE; + /// Function has typed arguments / class has typed props const HasTypeHints = ZEND_ACC_HAS_TYPE_HINTS; + /// Top-level class or function declaration const TopLevel = ZEND_ACC_TOP_LEVEL; + /// `op_array` or class is preloaded const Preloaded = ZEND_ACC_PRELOADED; + /// Deprecation flag const Deprecated = ZEND_ACC_DEPRECATED; + /// Function returning by reference const ReturnReference = ZEND_ACC_RETURN_REFERENCE; + /// Function has a return type const HasReturnType = ZEND_ACC_HAS_RETURN_TYPE; + /// Function with variable number of arguments const Variadic = ZEND_ACC_VARIADIC; + /// `op_array` has finally blocks (user only) const HasFinallyBlock = ZEND_ACC_HAS_FINALLY_BLOCK; + /// "main" `op_array` with `ZEND_DECLARE_CLASS_DELAYED` opcodes const EarlyBinding = ZEND_ACC_EARLY_BINDING; + /// Closure uses `$this` const UsesThis = ZEND_ACC_USES_THIS; + /// Call through user function trampoline + /// + /// # Example + /// - `__call` + /// - `__callStatic` const CallViaTrampoline = ZEND_ACC_CALL_VIA_TRAMPOLINE; + /// Disable inline caching const NeverCache = ZEND_ACC_NEVER_CACHE; + /// `op_array` is a clone of trait method const TraitClone = ZEND_ACC_TRAIT_CLONE; + /// Function is a constructor const IsConstructor = ZEND_ACC_CTOR; + /// Function is a closure const Closure = ZEND_ACC_CLOSURE; + /// Function is a fake closure const FakeClosure = ZEND_ACC_FAKE_CLOSURE; + /// Function is a generator const Generator = ZEND_ACC_GENERATOR; + /// Function was processed by pass two (user only) const DonePassTwo = ZEND_ACC_DONE_PASS_TWO; + /// `run_time_cache` allocated on heap (user only) const HeapRTCache = ZEND_ACC_HEAP_RT_CACHE; + /// `op_array` uses strict mode types const StrictTypes = ZEND_ACC_STRICT_TYPES; } } @@ -155,9 +236,13 @@ bitflags! { /// Flags for building constants. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct ConstantFlags: u32 { + /// Visibility public const Public = ZEND_ACC_PUBLIC; + /// Visibility protected const Protected = ZEND_ACC_PROTECTED; + /// Visibility private const Private = ZEND_ACC_PRIVATE; + /// Promoted constant const Promoted = ZEND_ACC_PROMOTED; } } @@ -166,9 +251,14 @@ bitflags! { /// Flags for building module global constants. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct GlobalConstantFlags: u32 { + /// No longer used -- always case-sensitive + #[deprecated(note = "No longer used -- always case-sensitive")] const CaseSensitive = CONST_CS; + /// Persistent const Persistent = CONST_PERSISTENT; + /// Can't be saved in file cache const NoFileCache = CONST_NO_FILE_CACHE; + /// Deprecated (this flag is not deprecated, it literally means the constant is deprecated) const Deprecated = CONST_DEPRECATED; } } @@ -177,7 +267,9 @@ bitflags! { /// Represents the result of a function. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct ZendResult: i32 { + /// Function call was successful. const Success = 0; + /// Function call failed. const Failure = -1; } } @@ -185,9 +277,13 @@ bitflags! { bitflags! { /// Represents permissions for where a configuration setting may be set. pub struct IniEntryPermission: u32 { + /// User const User = PHP_INI_USER; + /// Per directory const PerDir = PHP_INI_PERDIR; + /// System const System = PHP_INI_SYSTEM; + /// All const All = PHP_INI_ALL; } } @@ -195,28 +291,47 @@ bitflags! { bitflags! { /// Represents error types when used via php_error_docref for example. pub struct ErrorType: u32 { + /// Error const Error = E_ERROR; + /// Warning const Warning = E_WARNING; + /// Parse const Parse = E_PARSE; + /// Notice const Notice = E_NOTICE; + /// Core error const CoreError = E_CORE_ERROR; + /// Core warning const CoreWarning = E_CORE_WARNING; + /// Compile error const CompileError = E_COMPILE_ERROR; + /// Compile warning const CompileWarning = E_COMPILE_WARNING; + /// User error const UserError = E_USER_ERROR; + /// User warning const UserWarning = E_USER_WARNING; + /// User notice const UserNotice = E_USER_NOTICE; + /// Strict const Strict = E_STRICT; + /// Recoverable error const RecoverableError = E_RECOVERABLE_ERROR; + /// Deprecated const Deprecated = E_DEPRECATED; + /// User deprecated const UserDeprecated = E_USER_DEPRECATED; } } +/// Represents the type of a function. #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)] pub enum FunctionType { + /// Internal function Internal, + /// User function User, + /// Eval code Eval, } @@ -236,24 +351,43 @@ impl From for FunctionType { #[repr(C, u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum DataType { + /// Undefined Undef, + /// `null` Null, + /// `false` False, + /// `true` True, + /// Integer (the irony) Long, + /// Floating point number Double, + /// String String, + /// Array Array, + /// Iterable Iterable, + /// Object Object(Option<&'static str>), + /// Resource Resource, + /// Reference Reference, + /// Callable Callable, + /// Constant expression ConstantExpression, + /// Void Void, + /// Mixed Mixed, + /// Boolean Bool, + /// Pointer Ptr, + /// Indirect (internal) Indirect, } diff --git a/src/props.rs b/src/props.rs index e82bcb22d1..6c5386cf91 100644 --- a/src/props.rs +++ b/src/props.rs @@ -59,20 +59,21 @@ impl<'a, T: Clone + IntoZval + FromZval<'a>> Prop<'a> for T { } } +/// A getter for a property pub type PropertyGetter<'a, T> = Option PhpResult + Send + Sync + 'a>>; +/// A setter for a property pub type PropertySetter<'a, T> = Option PhpResult + Send + Sync + 'a>>; /// Represents a property added to a PHP class. -/// -/// There are two types of properties: -/// -/// * Field properties, where the data is stored inside a struct field. -/// * Method properties, where getter and/or setter functions are provided, -/// which are used to get and set the value of the property. pub enum Property<'a, T> { + /// Field properties, where the data is stored inside a struct field. Field(Box &mut dyn Prop) + Send + Sync>), + /// Method properties, where getter and/or setter functions are provided, + /// which are used to get and set the value of the property. Method { + /// Getter function for the property. get: PropertyGetter<'a, T>, + /// Setter function for the property. set: PropertySetter<'a, T>, }, } diff --git a/src/types/array.rs b/src/types/array.rs index 7d4205985a..db2fd15f66 100644 --- a/src/types/array.rs +++ b/src/types/array.rs @@ -578,13 +578,15 @@ pub struct Iter<'a> { end_pos: HashPosition, } +/// Represents the key of a PHP array, which can be either a long or a string. #[derive(Debug, PartialEq)] pub enum ArrayKey { + /// A numerical key. Long(i64), + /// A string key. String(String), } -/// Represent the key of a PHP array, which can be either a long or a string. impl ArrayKey { /// Check if the key is an integer. /// diff --git a/src/types/class_object.rs b/src/types/class_object.rs index c03ac321f3..ecf68aafad 100644 --- a/src/types/class_object.rs +++ b/src/types/class_object.rs @@ -27,7 +27,9 @@ use crate::{ #[repr(C)] #[derive(Debug)] pub struct ZendClassObject { + /// The object stored inside the class object. pub obj: Option, + /// The standard zend object. pub std: ZendObject, } diff --git a/src/types/iterable.rs b/src/types/iterable.rs index 24b226733d..3d99babbc7 100644 --- a/src/types/iterable.rs +++ b/src/types/iterable.rs @@ -8,7 +8,9 @@ use crate::types::{ZendHashTable, ZendIterator, Zval}; /// object implementing the Traversable interface. #[derive(Debug)] pub enum Iterable<'a> { + /// Iterable is an Array Array(&'a ZendHashTable), + /// Iterable is a Traversable Traversable(&'a mut ZendIterator), } diff --git a/src/types/object.rs b/src/types/object.rs index 1dc5f9c343..4ef55846b4 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -142,6 +142,11 @@ impl ZendObject { self.instance_of(ce::traversable()) } + /// Tries to call a method on the object. + /// + /// # Returns + /// Returns the return value of the method, or an error if the method + /// could not be found or called. #[inline(always)] pub fn try_call_method(&self, name: &str, params: Vec<&dyn IntoZvalDyn>) -> Result { let mut retval = Zval::new(); @@ -174,6 +179,7 @@ impl ZendObject { Ok(retval) } + /// Attempts to read a property from the Object. Returns a result containing /// the value of the property if it exists and can be read, and an /// [`Error`] otherwise. diff --git a/src/types/zval.rs b/src/types/zval.rs index d7ef148532..a1ef08bf88 100644 --- a/src/types/zval.rs +++ b/src/types/zval.rs @@ -219,6 +219,7 @@ impl Zval { } } + /// Attempts to call a method on the object contained in the zval. #[inline(always)] pub fn try_call_method(&self, name: &str, params: Vec<&dyn IntoZvalDyn>) -> Result { self.object() diff --git a/src/zend/class.rs b/src/zend/class.rs index 03d3418c02..bd2035f886 100644 --- a/src/zend/class.rs +++ b/src/zend/class.rs @@ -111,6 +111,7 @@ impl ClassEntry { unsafe { iterator.as_mut() } } + /// Gets the name of the class. pub fn name(&self) -> Option<&str> { unsafe { self.name.as_ref().and_then(|s| s.as_str().ok()) } } diff --git a/src/zend/function.rs b/src/zend/function.rs index a16ea1e61a..656a40e590 100644 --- a/src/zend/function.rs +++ b/src/zend/function.rs @@ -52,13 +52,16 @@ impl FunctionEntry { } } +/// PHP function. pub type Function = zend_function; impl Function { + /// Returns the function type. pub fn function_type(&self) -> FunctionType { FunctionType::from(unsafe { self.type_ }) } + /// Attempts to fetch a [`Function`] from the function name. pub fn try_from_function(name: &str) -> Option { unsafe { let res = zend_fetch_function_str(name.as_ptr() as *const c_char, name.len()); @@ -68,6 +71,8 @@ impl Function { Some(*res) } } + + /// Attempts to fetch a [`Function`] from the class and method name. pub fn try_from_method(class: &str, name: &str) -> Option { match ClassEntry::try_find(class) { None => None, diff --git a/src/zend/globals.rs b/src/zend/globals.rs index 475918df86..8363be6c02 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -375,11 +375,13 @@ impl SapiGlobals { let guard = SAPI_GLOBALS_LOCK.write(); GlobalWriteGuard { globals, guard } } - // Get the request info for the Sapi. + + /// Get the request info for the Sapi. pub fn request_info(&self) -> &SapiRequestInfo { &self.request_info } + /// Get the sapi headers for the Sapi. pub fn sapi_headers(&self) -> &SapiHeaders { &self.sapi_headers } @@ -388,6 +390,7 @@ impl SapiGlobals { pub type SapiHeaders = sapi_headers_struct; impl<'a> SapiHeaders { + /// Create an iterator over the headers. pub fn headers(&'a mut self) -> ZendLinkedListIterator<'a, SapiHeader> { self.headers.iter() } @@ -396,6 +399,10 @@ impl<'a> SapiHeaders { pub type SapiHeader = sapi_header_struct; impl<'a> SapiHeader { + /// Get the header as a string. + /// + /// # Panics + /// - If the header is not a valid UTF-8 string. pub fn as_str(&'a self) -> &'a str { unsafe { let slice = slice::from_raw_parts(self.header as *const u8, self.header_len); @@ -403,10 +410,12 @@ impl<'a> SapiHeader { } } + /// Returns the header name (key). pub fn name(&'a self) -> &'a str { self.as_str().split(':').next().unwrap_or("").trim() } + /// Returns the header value. pub fn value(&'a self) -> Option<&'a str> { self.as_str().split(':').nth(1).map(|s| s.trim()) } @@ -415,6 +424,7 @@ impl<'a> SapiHeader { pub type SapiRequestInfo = sapi_request_info; impl SapiRequestInfo { + /// Get the request method. pub fn request_method(&self) -> Option<&str> { if self.request_method.is_null() { return None; @@ -422,6 +432,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.request_method).to_str().ok() } } + /// Get the query string. pub fn query_string(&self) -> Option<&str> { if self.query_string.is_null() { return None; @@ -429,6 +440,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.query_string).to_str().ok() } } + /// Get the cookie data. pub fn cookie_data(&self) -> Option<&str> { if self.cookie_data.is_null() { return None; @@ -436,10 +448,12 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.cookie_data).to_str().ok() } } + /// Get the content length. pub fn content_length(&self) -> i64 { self.content_length } + /// Get the path info. pub fn path_translated(&self) -> Option<&str> { if self.path_translated.is_null() { return None; @@ -447,6 +461,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.path_translated).to_str().ok() } } + /// Get the request uri. pub fn request_uri(&self) -> Option<&str> { if self.request_uri.is_null() { return None; @@ -456,6 +471,7 @@ impl SapiRequestInfo { // Todo: request_body _php_stream + /// Get the content type. pub fn content_type(&self) -> Option<&str> { if self.content_type.is_null() { return None; @@ -463,20 +479,24 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.content_type).to_str().ok() } } + /// Whether the request consists of headers only. pub fn headers_only(&self) -> bool { self.headers_only } + /// Whether the request has no headers. pub fn no_headers(&self) -> bool { self.no_headers } + /// Whether the request headers have been read. pub fn headers_read(&self) -> bool { self.headers_read } // Todo: post_entry sapi_post_entry + /// Get the auth user. pub fn auth_user(&self) -> Option<&str> { if self.auth_user.is_null() { return None; @@ -484,6 +504,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.auth_user).to_str().ok() } } + /// Get the auth password. pub fn auth_password(&self) -> Option<&str> { if self.auth_password.is_null() { return None; @@ -491,6 +512,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.auth_password).to_str().ok() } } + /// Get the auth digest. pub fn auth_digest(&self) -> Option<&str> { if self.auth_digest.is_null() { return None; @@ -498,6 +520,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.auth_digest).to_str().ok() } } + /// Get argv0. pub fn argv0(&self) -> Option<&str> { if self.argv0.is_null() { return None; @@ -505,6 +528,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.argv0).to_str().ok() } } + /// Get the current user. pub fn current_user(&self) -> Option<&str> { if self.current_user.is_null() { return None; @@ -512,14 +536,17 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(self.current_user).to_str().ok() } } + /// Get the current user length. pub fn current_user_length(&self) -> i32 { self.current_user_length } + /// Get argvc. pub fn argvc(&self) -> i32 { self.argc } + /// Get argv. pub fn argv(&self) -> Option<&str> { if self.argv.is_null() { return None; @@ -527,6 +554,7 @@ impl SapiRequestInfo { unsafe { CStr::from_ptr(*self.argv).to_str().ok() } } + /// Get the protocol number. pub fn proto_num(&self) -> i32 { self.proto_num } @@ -567,6 +595,7 @@ impl FileGlobals { GlobalWriteGuard { globals, guard } } + /// Returns the stream wrappers pub fn stream_wrappers(&self) -> Option<&'static ZendHashTable> { unsafe { self.stream_wrappers.as_ref() } } diff --git a/src/zend/ini_entry_def.rs b/src/zend/ini_entry_def.rs index d9c8f64d8c..838d6076f3 100644 --- a/src/zend/ini_entry_def.rs +++ b/src/zend/ini_entry_def.rs @@ -49,6 +49,7 @@ impl IniEntryDef { Box::into_raw(Box::new(self)) } + /// Registers a list of ini entries. pub fn register(mut entries: Vec, module_number: i32) { entries.push(Self::end()); let entries = Box::into_raw(entries.into_boxed_slice()) as *const Self; diff --git a/src/zend/linked_list.rs b/src/zend/linked_list.rs index 481b229790..cc2ccb1133 100644 --- a/src/zend/linked_list.rs +++ b/src/zend/linked_list.rs @@ -2,9 +2,11 @@ use std::marker::PhantomData; use crate::ffi::{zend_llist, zend_llist_element, zend_llist_get_next_ex}; +/// PHP linked list pub type ZendLinkedList = zend_llist; impl ZendLinkedList { + /// Create an iterator over the linked list pub fn iter(&self) -> ZendLinkedListIterator { ZendLinkedListIterator::new(self) } diff --git a/src/zend/streams.rs b/src/zend/streams.rs index 8ea5da2287..153f667491 100644 --- a/src/zend/streams.rs +++ b/src/zend/streams.rs @@ -11,8 +11,10 @@ use crate::{ types::ZendStr, }; +/// Wrapper for PHP streams pub type StreamWrapper = php_stream_wrapper; +/// Stream opener function pub type StreamOpener = unsafe extern "C" fn( *mut StreamWrapper, *const std::ffi::c_char, @@ -28,6 +30,7 @@ pub type StreamOpener = unsafe extern "C" fn( ) -> *mut Stream; impl StreamWrapper { + /// Get wrapped stream by name pub fn get(name: &str) -> Option<&Self> { unsafe { let result = php_stream_locate_url_wrapper(name.as_ptr().cast(), ptr::null_mut(), 0); @@ -35,6 +38,7 @@ impl StreamWrapper { } } + /// Get mutable wrapped stream by name pub fn get_mut(name: &str) -> Option<&mut Self> { unsafe { let result = php_stream_locate_url_wrapper(name.as_ptr().cast(), ptr::null_mut(), 0); @@ -42,6 +46,10 @@ impl StreamWrapper { } } + /// Register stream wrapper for name + /// + /// # Panics + /// - If the name cannot be converted to a C string pub fn register(self, name: &str) -> Result { // We have to convert it to a static so owned streamwrapper doesn't get dropped. let copy = Box::new(self); @@ -55,6 +63,7 @@ impl StreamWrapper { } } + /// Register volatile stream wrapper for name pub fn register_volatile(self, name: &str) -> Result { // We have to convert it to a static so owned streamwrapper doesn't get dropped. let copy = Box::new(self); @@ -69,6 +78,10 @@ impl StreamWrapper { } } + /// Unregister stream wrapper by name + /// + /// # Panics + /// - If the name cannot be converted to a C string pub fn unregister(name: &str) -> Result<(), Error> { let name = std::ffi::CString::new(name).expect("Could not create C string for name!"); match unsafe { php_unregister_url_stream_wrapper(name.as_ptr()) } { @@ -77,6 +90,7 @@ impl StreamWrapper { } } + /// Unregister volatile stream wrapper by name pub fn unregister_volatile(name: &str) -> Result<(), Error> { let name = ZendStr::new(name, false); match unsafe { php_unregister_url_stream_wrapper_volatile((*name).as_ptr() as _) } { @@ -85,17 +99,21 @@ impl StreamWrapper { } } + /// Get the operations the stream wrapper can perform pub fn wops(&self) -> &php_stream_wrapper_ops { unsafe { &*self.wops } } + /// Get the mutable operations the stream can perform pub fn wops_mut(&mut self) -> &mut php_stream_wrapper_ops { unsafe { &mut *(self.wops as *mut php_stream_wrapper_ops) } } } +/// A PHP stream pub type Stream = php_stream; +/// Operations that can be performed with a stream wrapper pub type StreamWrapperOps = php_stream_wrapper_ops; impl StreamWrapperOps {}