graph_native/helpers.rs
1use crate::types::Address;
2
3/// Concatenate bytes with an i32 suffix — used for entity ID generation.
4/// Mirrors graph-ts Bytes.concatI32(): appends 4 little-endian bytes of the
5/// i32 to the byte array, returns 0x-prefixed hex string.
6pub fn concat_i32(left: &[u8], right: i32) -> String {
7 let mut result = left.to_vec();
8 result.extend_from_slice(&right.to_le_bytes());
9 format!("0x{}", hex::encode(&result))
10}
11
12/// Concatenate two byte arrays — used for entity ID generation.
13/// Mirrors graph-ts Bytes.concat()
14pub fn concat_bytes(left: &[u8], right: &[u8]) -> Vec<u8> {
15 let mut result = left.to_vec();
16 result.extend_from_slice(right);
17 result
18}
19
20/// Bytes type alias
21pub type Bytes = Vec<u8>;
22
23/// Decode a hex string into bytes.
24/// Mirrors graph-ts `Bytes.fromHexString()`.
25/// Accepts with or without `0x`/`0X` prefix.
26/// Panics on invalid hex input — matches graph-ts strict behavior.
27pub fn bytes_from_hex_string(s: &str) -> Bytes {
28 let stripped = s.strip_prefix("0x").or_else(|| s.strip_prefix("0X")).unwrap_or(s);
29 hex::decode(stripped).unwrap_or_else(|e| {
30 panic!("bytes_from_hex_string: invalid hex input '{}': {}", s, e)
31 })
32}
33
34/// Convert a UTF-8 string into bytes.
35/// Mirrors graph-ts `Bytes.fromUTF8()`.
36pub fn bytes_from_utf8(s: &str) -> Bytes {
37 s.as_bytes().to_vec()
38}
39
40/// Logging macros matching graph-ts log levels
41#[macro_export]
42macro_rules! info {
43 ($($arg:tt)*) => {
44 // TODO: wire to graph-node logging
45 eprintln!("[INFO] {}", format!($($arg)*));
46 };
47}
48
49#[macro_export]
50macro_rules! warning {
51 ($($arg:tt)*) => {
52 eprintln!("[WARN] {}", format!($($arg)*));
53 };
54}
55
56#[macro_export]
57macro_rules! error {
58 ($($arg:tt)*) => {
59 eprintln!("[ERROR] {}", format!($($arg)*));
60 };
61}
62
63#[macro_export]
64macro_rules! debug {
65 ($($arg:tt)*) => {
66 eprintln!("[DEBUG] {}", format!($($arg)*));
67 };
68}
69
70/// data_source module — mirrors graph-ts dataSource
71///
72/// PHASE C BLOCKER: Both functions below are stubs. They need runtime context
73/// from graph-node that is only available when the plugin is loaded by
74/// RuntimeHost::process_mapping_trigger:
75/// - network() needs the deployment's network string from DataSourceDetails
76/// - create() needs to register a dynamic data source with the SubgraphRunner
77/// via BlockState::created_data_sources
78///
79/// Until Phase C wiring, any handler using these will get wrong results.
80/// The transpiler should mark handlers using data_source::create() as
81/// unsupported (WASM fallback).
82///
83/// Tests for these functions are also blocked on Phase C — they require
84/// mocking graph-node's deployment context.
85pub mod data_source {
86 /// STUB: Returns hardcoded "mainnet". Phase C will read from DataSourceDetails.
87 pub fn network() -> String {
88 "mainnet".to_string()
89 }
90
91 /// STUB: No-op. Phase C will wire to BlockState::created_data_sources.
92 pub fn create(_template: &str, _address: &super::Address) {}
93}