mod legacy;
use pine_builtin_macro::BuiltinFunction;
use pine_core::PineVersion;
use pine_interpreter::{
Color, Input, InputOutput, InputValue, Interpreter, PineOutput, RuntimeError, Value,
};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
pub fn register<O: PineOutput + InputOutput>(version: PineVersion) -> Vec<(String, Value<O>)> {
if version >= PineVersion::V5 {
vec![("input".to_string(), register_v56())]
} else {
legacy::register()
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.int")]
struct InputInt<O: PineOutput + InputOutput> {
defval: f64,
#[arg(default = "")]
title: String,
#[arg(default = None)]
minval: Option<f64>,
#[arg(default = None)]
maxval: Option<f64>,
#[arg(default = None)]
step: Option<f64>,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
#[arg(default = Value::Na)]
options: Value<O>,
}
impl<O: PineOutput + InputOutput> InputInt<O> {
fn execute(&self, ctx: &mut Interpreter<O>) -> Result<Value<O>, RuntimeError> {
let _ = (
self.minval,
self.maxval,
self.step,
&self.tooltip,
&self.options,
);
ctx.output.add_input(Input {
kind: "int".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Int(self.defval as i64),
});
Ok(Value::Number(self.defval.trunc()))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.float")]
struct InputFloat<O: PineOutput + InputOutput> {
defval: f64,
#[arg(default = "")]
title: String,
#[arg(default = None)]
minval: Option<f64>,
#[arg(default = None)]
maxval: Option<f64>,
#[arg(default = None)]
step: Option<f64>,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
#[arg(default = Value::Na)]
options: Value<O>,
}
impl<O: PineOutput + InputOutput> InputFloat<O> {
fn execute(&self, ctx: &mut Interpreter<O>) -> Result<Value<O>, RuntimeError> {
let _ = (
self.minval,
self.maxval,
self.step,
&self.tooltip,
&self.options,
);
ctx.output.add_input(Input {
kind: "float".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Float(self.defval),
});
Ok(Value::Number(self.defval))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.bool", output = InputOutput)]
struct InputBool {
defval: bool,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
}
impl InputBool {
fn execute<O: PineOutput + InputOutput>(
&self,
ctx: &mut Interpreter<O>,
) -> Result<Value<O>, RuntimeError> {
let _ = &self.tooltip;
ctx.output.add_input(Input {
kind: "bool".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Bool(self.defval),
});
Ok(Value::Bool(self.defval))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.string")]
struct InputString<O: PineOutput + InputOutput> {
defval: String,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
#[arg(default = Value::Na)]
options: Value<O>,
}
impl<O: PineOutput + InputOutput> InputString<O> {
fn execute(&self, ctx: &mut Interpreter<O>) -> Result<Value<O>, RuntimeError> {
let _ = (&self.tooltip, &self.options);
ctx.output.add_input(Input {
kind: "string".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Str(self.defval.clone()),
});
Ok(Value::String(self.defval.clone()))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.session")]
struct InputSession<O: PineOutput + InputOutput> {
defval: String,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
#[arg(default = Value::Na)]
options: Value<O>,
}
impl<O: PineOutput + InputOutput> InputSession<O> {
fn execute(&self, ctx: &mut Interpreter<O>) -> Result<Value<O>, RuntimeError> {
let _ = (&self.tooltip, &self.options);
ctx.output.add_input(Input {
kind: "session".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Str(self.defval.clone()),
});
Ok(Value::String(self.defval.clone()))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.color", output = InputOutput)]
struct InputColor {
defval: Color,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
}
impl InputColor {
fn execute<O: PineOutput + InputOutput>(
&self,
ctx: &mut Interpreter<O>,
) -> Result<Value<O>, RuntimeError> {
let _ = &self.tooltip;
ctx.output.add_input(Input {
kind: "color".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Color(self.defval.clone()),
});
Ok(Value::Color(self.defval.clone()))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.time", output = InputOutput)]
struct InputTime {
defval: f64,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
}
impl InputTime {
fn execute<O: PineOutput + InputOutput>(
&self,
ctx: &mut Interpreter<O>,
) -> Result<Value<O>, RuntimeError> {
let _ = &self.tooltip;
ctx.output.add_input(Input {
kind: "time".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Int(self.defval as i64),
});
Ok(Value::Number(self.defval))
}
}
#[derive(BuiltinFunction)]
#[builtin(name = "input.source")]
struct InputSource<O: PineOutput + InputOutput> {
defval: Value<O>,
#[arg(default = "")]
title: String,
#[arg(default = "")]
group: String,
#[arg(default = "")]
tooltip: String,
}
impl<O: PineOutput + InputOutput> InputSource<O> {
fn execute(&self, ctx: &mut Interpreter<O>) -> Result<Value<O>, RuntimeError> {
let _ = &self.tooltip;
let series_id = match &self.defval {
Value::Series(series) => series.id.clone(),
_ => "source".to_string(),
};
ctx.output.add_input(Input {
kind: "source".to_string(),
title: self.title.clone(),
group: self.group.clone(),
default: InputValue::Str(series_id),
});
Ok(self.defval.clone())
}
}
fn register_v56<O: PineOutput + InputOutput>() -> Value<O> {
let mut members: HashMap<String, Value<O>> = HashMap::new();
members.insert("int".to_string(), InputInt::<O>::builtin_value());
members.insert("integer".to_string(), InputInt::<O>::builtin_value());
members.insert("float".to_string(), InputFloat::<O>::builtin_value());
members.insert("bool".to_string(), InputBool::builtin_value::<O>());
members.insert("string".to_string(), InputString::<O>::builtin_value());
members.insert("session".to_string(), InputSession::<O>::builtin_value());
members.insert("color".to_string(), InputColor::builtin_value::<O>());
members.insert("time".to_string(), InputTime::builtin_value::<O>());
members.insert("source".to_string(), InputSource::<O>::builtin_value());
Value::Object {
type_name: "input".to_string(),
fields: Rc::new(RefCell::new(members)),
call: None,
}
}