-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #423 from devraymondsh/develop
Improve rs_port stage 4
- Loading branch information
Showing
35 changed files
with
2,062 additions
and
1,440 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,22 @@ | ||
[package] | ||
name = "metacall" | ||
version = "0.3.1" | ||
repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" | ||
authors = ["Vicente Eduardo Ferrer Garcia <vic798@gmail.com>", "Swarnim Arun <swarnimarun11@gmail.com>"] | ||
authors = ["Mahdi Sharifi <devraymondsh@gmail.com>", "Vicente Eduardo Ferrer Garcia <vic798@gmail.com>", "Swarnim Arun <swarnimarun11@gmail.com>"] | ||
description = "Call NodeJS, TypeScript, Python, C#, Ruby... functions from Rust (a Rust Port for MetaCall)." | ||
edition = "2021" | ||
keywords = ["programming-language", "ffi", "polyglot", "metacall", "function-mesh", "inter-language", "polyglot-programming"] | ||
license = "Apache-2.0" | ||
name = "metacall" | ||
readme = "README.md" | ||
description = "Call NodeJS, TypeScript, Python, C#, Ruby... functions from Rust (a Rust Port for MetaCall)." | ||
repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" | ||
version = "0.4.0" | ||
|
||
[lib] | ||
name = "metacall" | ||
crate-type = ["lib"] # TODO: Once this is unified with the loader, we should use cdylib type | ||
crate-type = ["lib"] | ||
path = "src/lib.rs" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
concat-idents = "1.1.4" | ||
dyn-clone = "1.0.11" | ||
metacall-inline = { path = "./inline", version = "0.1.1" } | ||
metacall-inline = { path = "./inline", version = "0.2.0" } | ||
|
||
[build-dependencies] | ||
bindgen = { version = "0.64.0", default-features = false, features = ["runtime", "logging", "which-rustfmt"]} |
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,115 @@ | ||
use crate::types::MetacallValue; | ||
use std::any::Any; | ||
|
||
pub trait MetacallDowncast: Any { | ||
fn into_any(self: Box<Self>) -> Box<dyn Any>; | ||
fn as_any(&self) -> &dyn Any; | ||
fn as_any_mut(&mut self) -> &mut dyn Any; | ||
} | ||
impl<T: Any> MetacallDowncast for T { | ||
fn into_any(self: Box<Self>) -> Box<dyn Any> { | ||
self | ||
} | ||
fn as_any(&self) -> &dyn Any { | ||
self | ||
} | ||
fn as_any_mut(&mut self) -> &mut dyn Any { | ||
self | ||
} | ||
} | ||
impl dyn MetacallValue { | ||
/// Checks if the trait object is having the given type. | ||
pub fn is<T: MetacallValue>(&self) -> bool { | ||
MetacallDowncast::as_any(self).is::<T>() | ||
} | ||
|
||
/// Downcasts the inner value of the trait object and returns the ownership. | ||
pub fn downcast<T: MetacallValue>(self: Box<Self>) -> Result<T, Box<Self>> { | ||
if self.is::<T>() { | ||
Ok(*MetacallDowncast::into_any(self).downcast::<T>().unwrap()) | ||
} else { | ||
Err(self) | ||
} | ||
} | ||
|
||
/// Downcasts the inner value of the trait object and returns a reference. | ||
pub fn downcast_ref<T: MetacallValue>(&self) -> Option<&T> { | ||
MetacallDowncast::as_any(self).downcast_ref::<T>() | ||
} | ||
|
||
/// Downcasts the inner value of the trait object and returns a mutable reference. | ||
pub fn downcast_mut<T: MetacallValue>(&mut self) -> Option<&mut T> { | ||
MetacallDowncast::as_any_mut(self).downcast_mut::<T>() | ||
} | ||
} | ||
|
||
pub trait MetacallSealed {} | ||
impl<T: Clone> MetacallSealed for T {} | ||
impl MetacallSealed for str {} | ||
impl<T: Clone> MetacallSealed for [T] {} | ||
|
||
pub fn clone_box<T>(t: &T) -> Box<T> | ||
where | ||
T: ?Sized + MetacallClone, | ||
{ | ||
unsafe { | ||
let mut fat_ptr = t as *const T; | ||
let data_ptr = &mut fat_ptr as *mut *const T as *mut *mut (); | ||
|
||
assert_eq!(*data_ptr as *const (), t as *const T as *const ()); | ||
|
||
*data_ptr = <T as MetacallClone>::clone_box(t); | ||
|
||
Box::from_raw(fat_ptr as *mut T) | ||
} | ||
} | ||
|
||
pub trait MetacallClone: MetacallSealed { | ||
fn clone_box(&self) -> *mut (); | ||
} | ||
impl<T> MetacallClone for T | ||
where | ||
T: Clone, | ||
{ | ||
fn clone_box(&self) -> *mut () { | ||
Box::<T>::into_raw(Box::new(self.clone())) as *mut () | ||
} | ||
} | ||
|
||
impl MetacallClone for str { | ||
fn clone_box(&self) -> *mut () { | ||
Box::<str>::into_raw(Box::from(self)) as *mut () | ||
} | ||
} | ||
impl<T> MetacallClone for [T] | ||
where | ||
T: Clone, | ||
{ | ||
fn clone_box(&self) -> *mut () { | ||
Box::<[T]>::into_raw(self.iter().cloned().collect()) as *mut () | ||
} | ||
} | ||
impl<'c> Clone for Box<dyn MetacallValue + 'c> { | ||
fn clone(&self) -> Self { | ||
clone_box(&**self) | ||
} | ||
} | ||
impl<'c> Clone for Box<dyn MetacallValue + Send + 'c> { | ||
fn clone(&self) -> Self { | ||
clone_box(&**self) | ||
} | ||
} | ||
impl<'c> Clone for Box<dyn MetacallValue + Sync + 'c> { | ||
fn clone(&self) -> Self { | ||
clone_box(&**self) | ||
} | ||
} | ||
impl<'c> Clone for Box<dyn MetacallValue + Send + Sync + 'c> { | ||
fn clone(&self) -> Self { | ||
clone_box(&**self) | ||
} | ||
} | ||
|
||
pub fn metacall_implementer_to_traitobj(v: impl MetacallValue) -> Box<dyn MetacallValue> { | ||
Box::new(v) as Box<dyn MetacallValue> | ||
} |
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
Oops, something went wrong.