Skip to content

Commit 3475b96

Browse files
committed
feat: add rayforce memory bridge
1 parent 709896c commit 3475b96

8 files changed

Lines changed: 459 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[workspace]
22
members = [
3+
"crates/rayforce-sys",
34
"crates/raysense-cli",
45
"crates/raysense-core",
6+
"crates/raysense-memory",
57
]
68
resolver = "2"
79

crates/rayforce-sys/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "rayforce-sys"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
license.workspace = true
6+
links = "rayforce"
7+
8+
[build-dependencies]
9+

crates/rayforce-sys/build.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::env;
2+
use std::path::PathBuf;
3+
4+
fn main() {
5+
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
6+
let rayforce_dir = env::var_os("RAYFORCE_DIR")
7+
.map(PathBuf::from)
8+
.unwrap_or_else(|| manifest_dir.join("../../..").join("rayforce"));
9+
10+
let include_dir = rayforce_dir.join("include");
11+
let lib_dir = rayforce_dir.clone();
12+
let lib_path = lib_dir.join("librayforce.a");
13+
14+
if !lib_path.exists() {
15+
panic!(
16+
"missing {}; build it with `make -C {} lib` or set RAYFORCE_DIR",
17+
lib_path.display(),
18+
rayforce_dir.display()
19+
);
20+
}
21+
22+
println!("cargo:include={}", include_dir.display());
23+
println!("cargo:rustc-link-search=native={}", lib_dir.display());
24+
println!("cargo:rustc-link-lib=static=rayforce");
25+
26+
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") {
27+
println!("cargo:rustc-link-lib=m");
28+
println!("cargo:rustc-link-lib=pthread");
29+
} else {
30+
println!("cargo:rustc-link-lib=m");
31+
}
32+
33+
println!("cargo:rerun-if-env-changed=RAYFORCE_DIR");
34+
println!("cargo:rerun-if-changed={}", lib_path.display());
35+
println!(
36+
"cargo:rerun-if-changed={}",
37+
include_dir.join("rayforce.h").display()
38+
);
39+
}

crates/rayforce-sys/src/lib.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#![allow(non_camel_case_types)]
2+
3+
use std::ffi::CStr;
4+
use std::os::raw::{c_char, c_int};
5+
6+
pub const RAY_I32: i8 = 4;
7+
pub const RAY_I64: i8 = 5;
8+
pub const RAY_STR: i8 = 13;
9+
pub const RAY_TABLE: i8 = 98;
10+
11+
#[repr(C)]
12+
pub struct ray_t {
13+
_private: [u8; 0],
14+
}
15+
16+
unsafe extern "C" {
17+
pub fn ray_version_major() -> c_int;
18+
pub fn ray_version_minor() -> c_int;
19+
pub fn ray_version_patch() -> c_int;
20+
pub fn ray_version_string() -> *const c_char;
21+
22+
pub fn ray_release(v: *mut ray_t);
23+
24+
pub fn ray_sym_init() -> ray_err_t;
25+
pub fn ray_sym_destroy();
26+
pub fn ray_sym_intern(str: *const c_char, len: usize) -> i64;
27+
28+
pub fn ray_vec_new(type_: i8, capacity: i64) -> *mut ray_t;
29+
pub fn ray_vec_append(vec: *mut ray_t, elem: *const std::ffi::c_void) -> *mut ray_t;
30+
pub fn ray_str_vec_append(vec: *mut ray_t, s: *const c_char, len: usize) -> *mut ray_t;
31+
32+
pub fn ray_table_new(ncols: i64) -> *mut ray_t;
33+
pub fn ray_table_add_col(tbl: *mut ray_t, name_id: i64, col_vec: *mut ray_t) -> *mut ray_t;
34+
pub fn ray_table_ncols(tbl: *mut ray_t) -> i64;
35+
pub fn ray_table_nrows(tbl: *mut ray_t) -> i64;
36+
}
37+
38+
pub type ray_err_t = c_int;
39+
40+
pub const RAY_OK: ray_err_t = 0;
41+
42+
pub fn version_string() -> String {
43+
unsafe {
44+
let ptr = ray_version_string();
45+
if ptr.is_null() {
46+
return format!(
47+
"{}.{}.{}",
48+
ray_version_major(),
49+
ray_version_minor(),
50+
ray_version_patch()
51+
);
52+
}
53+
CStr::from_ptr(ptr).to_string_lossy().into_owned()
54+
}
55+
}

crates/raysense-cli/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ path = "src/main.rs"
1111
[dependencies]
1212
anyhow.workspace = true
1313
clap.workspace = true
14+
rayforce-sys = { path = "../rayforce-sys" }
1415
raysense-core = { path = "../raysense-core" }
16+
raysense-memory = { path = "../raysense-memory" }
1517
serde_json.workspace = true

crates/raysense-cli/src/main.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,58 @@ enum Command {
1717
path: PathBuf,
1818
#[arg(long)]
1919
json: bool,
20+
#[arg(long)]
21+
memory: bool,
22+
},
23+
RayforceVersion,
24+
Memory {
25+
path: PathBuf,
2026
},
2127
}
2228

2329
fn main() -> Result<()> {
2430
let args = Args::parse();
2531

2632
match args.command {
27-
Command::Observe { path, json } => {
33+
Command::Observe { path, json, memory } => {
2834
let report = scan_path(path)?;
2935
if json {
3036
println!("{}", serde_json::to_string_pretty(&report)?);
37+
} else if memory {
38+
let memory = raysense_memory::RayMemory::from_report(&report)?;
39+
print_memory_summary(&memory.summary());
3140
} else {
3241
print_summary(&report);
3342
}
3443
}
44+
Command::RayforceVersion => {
45+
println!("{}", rayforce_sys::version_string());
46+
}
47+
Command::Memory { path } => {
48+
let report = scan_path(path)?;
49+
let memory = raysense_memory::RayMemory::from_report(&report)?;
50+
print_memory_summary(&memory.summary());
51+
}
3552
}
3653

3754
Ok(())
3855
}
3956

57+
fn print_memory_summary(summary: &raysense_memory::MemorySummary) {
58+
println!(
59+
"files rows={} cols={}",
60+
summary.files.rows, summary.files.columns
61+
);
62+
println!(
63+
"functions rows={} cols={}",
64+
summary.functions.rows, summary.functions.columns
65+
);
66+
println!(
67+
"imports rows={} cols={}",
68+
summary.imports.rows, summary.imports.columns
69+
);
70+
}
71+
4072
fn print_summary(report: &raysense_core::ScanReport) {
4173
println!("snapshot {}", report.snapshot.snapshot_id);
4274
println!("root {}", report.snapshot.root.display());

crates/raysense-memory/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "raysense-memory"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
license.workspace = true
6+
7+
[dependencies]
8+
rayforce-sys = { path = "../rayforce-sys" }
9+
raysense-core = { path = "../raysense-core" }
10+
thiserror.workspace = true

0 commit comments

Comments
 (0)