-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ensure CLI-Extension compatibility (#108)
* Change describe types to C ABI, check ext-php-rs version Rust doesn't have a stable ABI so the describe function and types are now C ABI compatible, however, the internal types `Cow`, `Vec`, `Option` aren't. Check `ext-php-rs` versions to check compatibility between the CLI and the extension. * CLI requires 0.7.1 * Bump versions * Replace standard library types with ABI-stable replacements * Change option type
- Loading branch information
1 parent
fa05703
commit d9e40ea
Showing
11 changed files
with
225 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
//! ABI-stable standard library types. | ||
//! | ||
//! The description module is used by the `cargo-php` sub-command to retrieve | ||
//! information about the extension. As Rust does not have a stable ABI, it is | ||
//! not as simple as working in the Rust domain, as if the CLI and extension | ||
//! Rust versions do not match, it cannot be assumed that the types have the | ||
//! same memory layout. | ||
//! | ||
//! This module contains thin wrappers around standard library types used by the | ||
//! describe function to provide some sort of ABI-stability. | ||
//! | ||
//! As a general rule of thumb, no Rust type is ABI-stable. Strictly speaking, | ||
//! [`usize`] should not be in use, but rather `size_t` or a similar type, | ||
//! however these are currently unstable. | ||
use std::{fmt::Display, ops::Deref, vec::Vec as StdVec}; | ||
|
||
/// An immutable, ABI-stable [`Vec`][std::vec::Vec]. | ||
#[repr(C)] | ||
pub struct Vec<T> { | ||
ptr: *mut T, | ||
len: usize, | ||
} | ||
|
||
impl<T> Deref for Vec<T> { | ||
type Target = [T]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
unsafe { std::slice::from_raw_parts(self.ptr, self.len) } | ||
} | ||
} | ||
|
||
impl<T> Drop for Vec<T> { | ||
fn drop(&mut self) { | ||
unsafe { Box::from_raw(std::ptr::slice_from_raw_parts_mut(self.ptr, self.len)) }; | ||
} | ||
} | ||
|
||
impl<T> From<StdVec<T>> for Vec<T> { | ||
fn from(vec: StdVec<T>) -> Self { | ||
let vec = vec.into_boxed_slice(); | ||
let len = vec.len(); | ||
let ptr = Box::into_raw(vec) as *mut T; | ||
|
||
Self { ptr, len } | ||
} | ||
} | ||
|
||
/// An immutable, ABI-stable borrowed [`&'static str`][str]. | ||
#[repr(C)] | ||
pub struct Str { | ||
ptr: *const u8, | ||
len: usize, | ||
} | ||
|
||
impl Str { | ||
/// Returns the string as a string slice. | ||
/// | ||
/// The lifetime is `'static` and can outlive the [`Str`] object, as you can | ||
/// only initialize a [`Str`] through a static reference. | ||
pub fn str(&self) -> &'static str { | ||
unsafe { std::str::from_utf8_unchecked(std::slice::from_raw_parts(self.ptr, self.len)) } | ||
} | ||
} | ||
|
||
impl From<&'static str> for Str { | ||
fn from(val: &'static str) -> Self { | ||
let ptr = val.as_ptr(); | ||
let len = val.len(); | ||
Self { ptr, len } | ||
} | ||
} | ||
|
||
impl AsRef<str> for Str { | ||
fn as_ref(&self) -> &str { | ||
self.str() | ||
} | ||
} | ||
|
||
impl Display for Str { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
self.str().fmt(f) | ||
} | ||
} | ||
|
||
/// An ABI-stable [`Option`][std::option::Option]. | ||
#[repr(C, u8)] | ||
pub enum Option<T> { | ||
Some(T), | ||
None, | ||
} |
Oops, something went wrong.