use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisContext {
pub functions: Vec<FunctionContext>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionContext {
pub name: String,
pub c_signature: String,
pub ownership: HashMap<String, OwnershipInfo>,
pub lifetimes: Vec<LifetimeInfo>,
pub lock_mappings: HashMap<String, Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OwnershipInfo {
pub kind: String,
pub confidence: f64,
pub reason: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LifetimeInfo {
pub variable: String,
pub scope_depth: usize,
pub escapes: bool,
pub depends_on: Vec<String>,
}
#[derive(Debug, Default)]
pub struct ContextBuilder {
functions: Vec<FunctionContext>,
}
impl ContextBuilder {
pub fn new() -> Self {
Self {
functions: Vec::new(),
}
}
pub fn build(&self) -> AnalysisContext {
AnalysisContext {
functions: self.functions.clone(),
}
}
pub fn add_function(&mut self, name: &str, c_signature: &str) -> &mut Self {
self.functions.push(FunctionContext {
name: name.to_string(),
c_signature: c_signature.to_string(),
ownership: HashMap::new(),
lifetimes: Vec::new(),
lock_mappings: HashMap::new(),
});
self
}
pub fn add_ownership(
&mut self,
function: &str,
variable: &str,
kind: &str,
confidence: f64,
reason: &str,
) -> &mut Self {
if let Some(func) = self.functions.iter_mut().find(|f| f.name == function) {
func.ownership.insert(
variable.to_string(),
OwnershipInfo {
kind: kind.to_string(),
confidence,
reason: reason.to_string(),
},
);
}
self
}
pub fn add_lifetime(
&mut self,
function: &str,
variable: &str,
scope_depth: usize,
escapes: bool,
) -> &mut Self {
if let Some(func) = self.functions.iter_mut().find(|f| f.name == function) {
func.lifetimes.push(LifetimeInfo {
variable: variable.to_string(),
scope_depth,
escapes,
depends_on: Vec::new(),
});
}
self
}
pub fn add_lock_mapping(
&mut self,
function: &str,
lock: &str,
protected_data: Vec<String>,
) -> &mut Self {
if let Some(func) = self.functions.iter_mut().find(|f| f.name == function) {
func.lock_mappings.insert(lock.to_string(), protected_data);
}
self
}
pub fn to_json(&self) -> Result<String, serde_json::Error> {
let context = self.build();
serde_json::to_string_pretty(&context)
}
}