use num_bigint::BigInt;
use super::{CallArgs, MontyObject, NamedValues, ObjectRef};
pub use crate::graph::{ClassTypeNode, GraphError, MontyGraph, MontyNode, NodeId};
use crate::{file_mode::FileMode, os::TimeCaller};
pub type CallArgsParts = (MontyGraph, Vec<NodeId>, Vec<(NodeId, NodeId)>);
pub type CallArgsPartsRef<'a> = (&'a MontyGraph, &'a [NodeId], &'a [(NodeId, NodeId)]);
pub type CallArgsPartsMut<'a> = (&'a mut MontyGraph, &'a mut Vec<NodeId>, &'a mut Vec<(NodeId, NodeId)>);
#[must_use]
pub fn graph_parts(value: &MontyObject) -> (&MontyGraph, NodeId) {
(&value.graph, value.root)
}
#[must_use]
pub fn into_graph_parts(value: MontyObject) -> (MontyGraph, NodeId) {
(value.graph, value.root)
}
pub fn object_from_graph(graph: MontyGraph, root: NodeId) -> Result<MontyObject, GraphError> {
MontyObject::new(graph, root)
}
#[must_use]
pub fn object_from_node(node: MontyNode) -> MontyObject {
MontyObject::leaf(node)
}
#[must_use]
pub fn root_node(value: &MontyObject) -> &MontyNode {
value.root_node()
}
#[must_use]
pub fn node(value: ObjectRef<'_>) -> &MontyNode {
value.node()
}
#[must_use]
pub fn child(value: ObjectRef<'_>, id: NodeId) -> ObjectRef<'_> {
value.child(id)
}
#[must_use]
pub fn call_args_parts(args: &CallArgs) -> CallArgsPartsRef<'_> {
(&args.graph, &args.arg_ids, &args.kwarg_ids)
}
#[must_use]
pub fn call_args_parts_mut(args: &mut CallArgs) -> CallArgsPartsMut<'_> {
(&mut args.graph, &mut args.arg_ids, &mut args.kwarg_ids)
}
#[must_use]
pub fn into_call_args_parts(args: CallArgs) -> CallArgsParts {
(args.graph, args.arg_ids, args.kwarg_ids)
}
pub fn call_args_from_parts(
graph: MontyGraph,
arg_ids: Vec<NodeId>,
kwarg_ids: Vec<(NodeId, NodeId)>,
) -> Result<CallArgs, GraphError> {
let args = CallArgs {
graph,
arg_ids,
kwarg_ids,
};
args.check_roots()?;
Ok(args)
}
#[must_use]
pub fn named_values_parts(values: &NamedValues) -> (&MontyGraph, &[(String, NodeId)]) {
(&values.graph, &values.names)
}
#[must_use]
pub fn into_named_values_parts(values: NamedValues) -> (MontyGraph, Vec<(String, NodeId)>) {
(values.graph, values.names)
}
pub fn named_values_from_parts(graph: MontyGraph, names: Vec<(String, NodeId)>) -> Result<NamedValues, GraphError> {
let values = NamedValues { graph, names };
values.check_roots()?;
Ok(values)
}
pub fn push_arg(args: &mut CallArgs, value: impl PushValue) -> NodeId {
let id = value.push_into(&mut args.graph);
args.arg_ids.push(id);
id
}
pub fn push_kwarg(args: &mut CallArgs, name: &str, value: impl PushValue) {
let key = args.graph.push(MontyNode::String(name.to_owned()));
let value = value.push_into(&mut args.graph);
args.kwarg_ids.push((key, value));
}
pub fn push_named(values: &mut NamedValues, name: impl Into<String>, value: impl PushValue) -> NodeId {
let id = value.push_into(&mut values.graph);
values.names.push((name.into(), id));
id
}
pub trait PushValue {
fn push_into(self, graph: &mut MontyGraph) -> NodeId;
}
impl PushValue for MontyNode {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(self)
}
}
impl PushValue for String {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::String(self))
}
}
impl PushValue for Vec<u8> {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::Bytes(self))
}
}
impl PushValue for i64 {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::Int(self))
}
}
impl PushValue for u64 {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(i64::try_from(self).map_or_else(|_| MontyNode::BigInt(BigInt::from(self)), MontyNode::Int))
}
}
impl PushValue for bool {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::Bool(self))
}
}
impl PushValue for FileMode {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::String(self.as_str().to_owned()))
}
}
impl PushValue for TimeCaller {
fn push_into(self, graph: &mut MontyGraph) -> NodeId {
graph.push(MontyNode::String(self.as_str().to_owned()))
}
}