Skip to content

Commit

Permalink
Split cairo-lang-macro crate into two (api <> abi)
Browse files Browse the repository at this point in the history
commit-id:54582a03
  • Loading branch information
maciektr committed Feb 21, 2024
1 parent d86a629 commit b75f088
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 137 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ members = [
"extensions/scarb-cairo-run",
"extensions/scarb-cairo-test",
"extensions/scarb-snforge-test-collector",
"plugins/cairo-lang-macro-attributes",
"plugins/cairo-lang-macro",
"plugins/cairo-lang-macro-attributes",
"plugins/cairo-lang-macro-stable",
"utils/create-output-dir",
"utils/scarb-build-metadata",
"utils/scarb-test-support",
Expand Down
6 changes: 3 additions & 3 deletions plugins/cairo-lang-macro-attributes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ pub fn attribute_macro(_args: TokenStream, input: TokenStream) -> TokenStream {
#item

#[no_mangle]
pub unsafe extern "C" fn expand(token_stream: cairo_lang_macro::stable_abi::StableTokenStream) -> cairo_lang_macro::stable_abi::StableProcMacroResult {
let token_stream = token_stream.into_token_stream();
pub unsafe extern "C" fn expand(token_stream: cairo_lang_macro_stable::StableTokenStream) -> cairo_lang_macro_stable::StableProcMacroResult {
let token_stream = TokenStream::from_stable(token_stream);
let result = #item_name(token_stream);
cairo_lang_macro::stable_abi::StableProcMacroResult::from_proc_macro_result(result)
result.into_stable()
}
};
TokenStream::from(expanded)
Expand Down
18 changes: 18 additions & 0 deletions plugins/cairo-lang-macro-stable/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "cairo-lang-macro-stable"
version = "0.0.1"
edition.workspace = true

authors.workspace = true
categories = ["development-tools"]
description = "Cairo procedural macro stable ABI interface primitives."
homepage.workspace = true
keywords = ["scarb"]
license.workspace = true
readme = "README.md"
repository.workspace = true

[dependencies]
anyhow.workspace = true
serde.workspace = true
serde_json.workspace = true
3 changes: 3 additions & 0 deletions plugins/cairo-lang-macro-stable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# cairo-lang-macro-stable

Stable interface for Scarb procedural macros.
51 changes: 51 additions & 0 deletions plugins/cairo-lang-macro-stable/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::ffi::CString;
use std::os::raw::c_char;

/// Token stream.
///
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug)]
pub struct StableTokenStream(pub *mut c_char);

#[repr(C)]
#[derive(Debug)]
pub enum StableAuxData {
None,
Some(*mut c_char),
}

/// Procedural macro result.
///
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug)]
pub enum StableProcMacroResult {
/// Plugin has not taken any action.
Leave,
/// Plugin generated [`StableTokenStream`] replacement.
Replace {
token_stream: StableTokenStream,
aux_data: StableAuxData,
},
/// Plugin ordered item removal.
Remove,
}

impl StableTokenStream {
/// Convert to String.
///
/// # Safety
pub unsafe fn to_string(&self) -> String {
raw_to_string(self.0)
}
}

unsafe fn raw_to_string(raw: *mut c_char) -> String {
if raw.is_null() {
String::default()
} else {
let cstr = CString::from_raw(raw);
cstr.to_string_lossy().to_string()
}
}
1 change: 1 addition & 0 deletions plugins/cairo-lang-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ repository.workspace = true
[dependencies]
anyhow.workspace = true
cairo-lang-macro-attributes = { path = "../cairo-lang-macro-attributes" }
cairo-lang-macro-stable = { path = "../cairo-lang-macro-stable" }
serde.workspace = true
serde_json.workspace = true
104 changes: 101 additions & 3 deletions plugins/cairo-lang-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use serde_json::Value;
use std::ffi::{c_char, CString};
use std::fmt::Display;

pub use cairo_lang_macro_attributes::*;

#[doc(hidden)]
pub mod stable_abi;
use cairo_lang_macro_stable::{StableAuxData, StableProcMacroResult, StableTokenStream};

#[derive(Debug)]
pub enum ProcMacroResult {
Expand Down Expand Up @@ -48,3 +47,102 @@ impl AuxData {
self.0
}
}

impl ProcMacroResult {
/// Convert to FFI-safe representation.
///
/// # Safety
#[doc(hidden)]
pub fn into_stable(self) -> StableProcMacroResult {
match self {
ProcMacroResult::Leave => StableProcMacroResult::Leave,
ProcMacroResult::Remove => StableProcMacroResult::Remove,
ProcMacroResult::Replace {
token_stream,
aux_data,
} => StableProcMacroResult::Replace {
token_stream: token_stream.into_stable(),
aux_data: AuxData::maybe_into_stable(aux_data),
},
}
}

/// Convert to native Rust representation.
///
/// # Safety
#[doc(hidden)]
pub unsafe fn from_stable(result: StableProcMacroResult) -> Self {
match result {
StableProcMacroResult::Leave => ProcMacroResult::Leave,
StableProcMacroResult::Remove => ProcMacroResult::Remove,
StableProcMacroResult::Replace {
token_stream,
aux_data,
} => ProcMacroResult::Replace {
token_stream: TokenStream::from_stable(token_stream),
aux_data: AuxData::from_stable(aux_data).unwrap(),
},
}
}
}

impl TokenStream {
/// Convert to FFI-safe representation.
///
/// # Safety
#[doc(hidden)]
pub fn into_stable(self) -> StableTokenStream {
let cstr = CString::new(self.0).unwrap();
StableTokenStream(cstr.into_raw())
}

/// Convert to native Rust representation.
///
/// # Safety
#[doc(hidden)]
pub unsafe fn from_stable(token_stream: StableTokenStream) -> Self {
Self::new(token_stream.to_string())
}
}

impl AuxData {
/// Convert to FFI-safe representation.
///
/// # Safety
pub fn maybe_into_stable(aux_data: Option<Self>) -> StableAuxData {
if let Some(aux_data) = aux_data {
aux_data.into_stable()
} else {
StableAuxData::None
}
}

/// Convert to FFI-safe representation.
///
/// # Safety
#[doc(hidden)]
pub fn into_stable(self) -> StableAuxData {
let cstr = CString::new(self.0.to_string()).unwrap();
StableAuxData::Some(cstr.into_raw())
}

/// Convert to native Rust representation.
///
/// # Safety
#[doc(hidden)]
pub unsafe fn from_stable(aux_data: StableAuxData) -> Result<Option<Self>, serde_json::Error> {
match aux_data {
StableAuxData::None => Ok(None),
StableAuxData::Some(raw) => Some(Self::try_new(raw_to_string(raw))).transpose(),
}
}
}

unsafe fn raw_to_string(raw: *mut c_char) -> String {
if raw.is_null() {
String::default()
} else {
let cstr = CString::from_raw(raw);
cstr.to_string_lossy().to_string()
}
}
124 changes: 0 additions & 124 deletions plugins/cairo-lang-macro/src/stable_abi.rs

This file was deleted.

1 change: 1 addition & 0 deletions scarb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ redb.workspace = true
reqwest.workspace = true
scarb-build-metadata = { path = "../utils/scarb-build-metadata" }
cairo-lang-macro = { path = "../plugins/cairo-lang-macro" }
cairo-lang-macro-stable = { path = "../plugins/cairo-lang-macro-stable" }
scarb-metadata = { path = "../scarb-metadata", default-features = false, features = ["builder"] }
scarb-ui = { path = "../utils/scarb-ui" }
semver.workspace = true
Expand Down
Loading

0 comments on commit b75f088

Please sign in to comment.