1use std::collections::HashMap;
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct Color {
8 pub r: u8, pub g: u8, pub b: u8, pub t: u8, }
13
14impl Color {
15 pub fn new(r: u8, g: u8, b: u8, t: u8) -> Self {
16 Color { r, g, b, t }
17 }
18}
19
20#[derive(Clone, Debug)]
22pub struct Label {
23 pub x: f64,
24 pub y: f64,
25 pub text: String,
26 pub xloc: String,
27 pub yloc: String,
28 pub color: Option<Color>,
29 pub style: String,
30 pub textcolor: Option<Color>,
31 pub size: String,
32 pub textalign: String,
33 pub tooltip: Option<String>,
34 pub text_font_family: String,
35}
36
37#[derive(Clone, Debug)]
40pub struct FillObject {
41 pub id1: Option<usize>,
43 pub id2: Option<usize>,
45 pub color: Option<Color>,
46 pub title: String,
47}
48
49#[derive(Clone, Debug, Default)]
51pub struct GlobalContext {
52 pub bgcolor: Option<Color>,
54 pub barcolor: Option<Color>,
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq)]
60pub enum Frequency {
61 All,
63 OncePerBar,
65 OncePerBarClose,
67}
68
69impl Frequency {
70 pub fn from_const(value: &str) -> Frequency {
72 match value {
73 "freq_all" => Frequency::All,
74 "freq_once_per_bar_close" => Frequency::OncePerBarClose,
75 _ => Frequency::OncePerBar,
76 }
77 }
78}
79
80#[derive(Clone, Debug, Default)]
84pub struct AlertCondition {
85 pub title: String,
86 pub message: String,
87 pub frequency: Option<Frequency>,
88}
89
90#[derive(Clone, Debug, Default)]
92pub struct Indicator {
93 pub title: String,
94 pub shorttitle: String,
95 pub overlay: bool,
96 pub format: String,
97 pub precision: Option<i64>,
98 pub timeframe: String,
99}
100
101#[derive(Clone, Debug, Default)]
103pub struct Library {
104 pub title: String,
105 pub overlay: bool,
106 pub dynamic_requests: Option<bool>,
107}
108
109#[derive(Clone, Debug)]
111pub struct LineObject {
112 pub x1: f64,
113 pub y1: f64,
114 pub x2: f64,
115 pub y2: f64,
116 pub xloc: String,
117 pub extend: String,
118 pub color: Option<Color>,
119 pub style: String,
120 pub width: f64,
121}
122
123#[derive(Clone, Debug, Default)]
125pub struct TableCell {
126 pub text: String,
127 pub text_color: Option<Color>,
128 pub bgcolor: Option<Color>,
129 pub text_size: String,
130 pub text_halign: String,
131 pub text_valign: String,
132}
133
134#[derive(Clone, Debug)]
136pub struct Table {
137 pub position: String,
138 pub columns: usize,
139 pub rows: usize,
140 pub bgcolor: Option<Color>,
141 pub cells: HashMap<(usize, usize), TableCell>,
142}
143
144#[derive(Clone, Debug)]
145pub struct PineBox {
146 pub left: f64,
147 pub top: f64,
148 pub right: f64,
149 pub bottom: f64,
150 pub border_color: Option<Color>,
151 pub border_width: f64,
152 pub border_style: String,
153 pub extend: String,
154 pub xloc: String,
155 pub bgcolor: Option<Color>,
156 pub text: String,
157 pub text_size: f64,
158 pub text_color: Option<Color>,
159 pub text_halign: String,
160 pub text_valign: String,
161 pub text_wrap: String,
162 pub text_font_family: String,
163}
164
165#[derive(Clone, Debug, Default)]
167pub struct Plot {
168 pub series: f64,
169 pub title: String,
170 pub color: Option<Color>,
171 pub linewidth: f64,
172 pub style: String,
173 pub trackprice: bool,
174 pub histbase: f64,
175 pub offset: f64,
176 pub join: bool,
177 pub editable: bool,
178 pub show_last: Option<f64>,
179 pub display: String,
180 pub format: Option<String>,
181 pub precision: Option<f64>,
182 pub force_overlay: bool,
183 pub linestyle: String,
184}
185
186#[derive(Clone, Debug)]
188pub struct Plotarrow {
189 pub series: f64,
190 pub title: String,
191 pub colorup: Option<Color>,
192 pub colordown: Option<Color>,
193 pub offset: f64,
194 pub minheight: f64,
195 pub maxheight: f64,
196 pub editable: bool,
197 pub show_last: Option<f64>,
198 pub display: String,
199 pub format: Option<String>,
200 pub precision: Option<f64>,
201 pub force_overlay: bool,
202}
203
204#[derive(Clone, Debug)]
206pub struct Plotbar {
207 pub open: f64,
208 pub high: f64,
209 pub low: f64,
210 pub close: f64,
211 pub title: String,
212 pub color: Option<Color>,
213 pub editable: bool,
214 pub show_last: Option<f64>,
215 pub display: String,
216 pub format: Option<String>,
217 pub precision: Option<f64>,
218 pub force_overlay: bool,
219}
220
221#[derive(Clone, Debug)]
223pub struct Plotcandle {
224 pub open: f64,
225 pub high: f64,
226 pub low: f64,
227 pub close: f64,
228 pub title: String,
229 pub color: Option<Color>,
230 pub wickcolor: Option<Color>,
231 pub editable: bool,
232 pub show_last: Option<f64>,
233 pub bordercolor: Option<Color>,
234 pub display: String,
235 pub format: Option<String>,
236 pub precision: Option<f64>,
237 pub force_overlay: bool,
238}
239
240#[derive(Clone, Debug)]
242pub struct Plotchar {
243 pub series: f64,
244 pub title: String,
245 pub char: String,
246 pub location: String,
247 pub color: Option<Color>,
248 pub offset: f64,
249 pub text: String,
250 pub textcolor: Option<Color>,
251 pub editable: bool,
252 pub size: String,
253 pub show_last: Option<f64>,
254 pub display: String,
255 pub format: Option<String>,
256 pub precision: Option<f64>,
257 pub force_overlay: bool,
258}
259
260#[derive(Clone, Debug)]
262pub struct Plotshape {
263 pub series: f64,
264 pub title: String,
265 pub style: String,
266 pub location: String,
267 pub color: Option<Color>,
268 pub offset: f64,
269 pub text: String,
270 pub textcolor: Option<Color>,
271 pub editable: bool,
272 pub size: String,
273 pub show_last: Option<f64>,
274 pub display: String,
275 pub format: Option<String>,
276 pub precision: Option<f64>,
277 pub force_overlay: bool,
278}
279
280#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282pub enum LogLevel {
283 Info,
284 Warning,
285 Error,
286}
287
288#[derive(Debug, Clone)]
290pub struct LogEntry {
291 pub level: LogLevel,
292 pub message: String,
293}
294
295#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
301#[serde(untagged)]
302pub enum InputValue {
303 Bool(bool),
304 Int(i64),
305 Float(f64),
306 Str(String),
307 #[serde(skip)]
308 Color(Color),
309}
310
311#[derive(Debug, Clone)]
316pub struct Input {
317 pub kind: String,
320 pub title: String,
322 pub group: String,
324 pub default: InputValue,
326 pub value: InputValue,
327}
328
329pub trait PineOutput: Default + Clone + std::fmt::Debug + 'static {
334 fn clear(&mut self);
336}
337
338pub trait LogOutput: PineOutput {
340 fn add_log(&mut self, level: LogLevel, message: String);
342 fn get_logs(&self) -> &[LogEntry];
344}
345
346#[macro_export]
353macro_rules! impl_output_traits_delegate {
354 ($type:ty, $field:ident) => {
355 impl $crate::LogOutput for $type {
356 fn add_log(&mut self, level: $crate::LogLevel, message: String) {
357 self.$field.add_log(level, message)
358 }
359 fn get_logs(&self) -> &[$crate::LogEntry] {
360 self.$field.get_logs()
361 }
362 }
363
364 impl $crate::PlotOutput for $type {
365 fn add_plot(&mut self, plot: $crate::Plot) {
366 self.$field.add_plot(plot)
367 }
368 fn plots(&self) -> &[$crate::Plot] {
369 self.$field.plots()
370 }
371 fn add_plotarrow(&mut self, arrow: $crate::Plotarrow) {
372 self.$field.add_plotarrow(arrow)
373 }
374 fn plotarrows(&self) -> &[$crate::Plotarrow] {
375 self.$field.plotarrows()
376 }
377 fn add_plotbar(&mut self, bar: $crate::Plotbar) {
378 self.$field.add_plotbar(bar)
379 }
380 fn plotbars(&self) -> &[$crate::Plotbar] {
381 self.$field.plotbars()
382 }
383 fn add_plotcandle(&mut self, candle: $crate::Plotcandle) {
384 self.$field.add_plotcandle(candle)
385 }
386 fn plotcandles(&self) -> &[$crate::Plotcandle] {
387 self.$field.plotcandles()
388 }
389 fn add_plotchar(&mut self, char: $crate::Plotchar) {
390 self.$field.add_plotchar(char)
391 }
392 fn plotchars(&self) -> &[$crate::Plotchar] {
393 self.$field.plotchars()
394 }
395 fn add_plotshape(&mut self, shape: $crate::Plotshape) {
396 self.$field.add_plotshape(shape)
397 }
398 fn plotshapes(&self) -> &[$crate::Plotshape] {
399 self.$field.plotshapes()
400 }
401 }
402
403 impl $crate::LabelOutput for $type {
404 fn add_label(&mut self, label: $crate::Label) -> usize {
405 self.$field.add_label(label)
406 }
407 fn get_label(&self, id: usize) -> Option<&$crate::Label> {
408 self.$field.get_label(id)
409 }
410 fn get_label_mut(&mut self, id: usize) -> Option<&mut $crate::Label> {
411 self.$field.get_label_mut(id)
412 }
413 fn delete_label(&mut self, id: usize) -> bool {
414 self.$field.delete_label(id)
415 }
416 }
417
418 impl $crate::BoxOutput for $type {
419 fn add_box(&mut self, box_obj: $crate::PineBox) -> usize {
420 self.$field.add_box(box_obj)
421 }
422 fn get_box(&self, id: usize) -> Option<&$crate::PineBox> {
423 self.$field.get_box(id)
424 }
425 fn get_box_mut(&mut self, id: usize) -> Option<&mut $crate::PineBox> {
426 self.$field.get_box_mut(id)
427 }
428 fn delete_box(&mut self, id: usize) -> bool {
429 self.$field.delete_box(id)
430 }
431 }
432
433 impl $crate::InputOutput for $type {
434 fn add_input(&mut self, input: $crate::Input) {
435 self.$field.add_input(input)
436 }
437 fn inputs(&self) -> &[$crate::Input] {
438 self.$field.inputs()
439 }
440 }
441
442 impl $crate::MetadataOutput for $type {
443 fn set_indicator(&mut self, indicator: $crate::Indicator) {
444 self.$field.set_indicator(indicator)
445 }
446 fn indicator(&self) -> Option<&$crate::Indicator> {
447 self.$field.indicator()
448 }
449 fn set_library(&mut self, library: $crate::Library) {
450 self.$field.set_library(library)
451 }
452 fn library(&self) -> Option<&$crate::Library> {
453 self.$field.library()
454 }
455 }
456
457 impl $crate::AlertConditionOutput for $type {
458 fn add_alertcondition(&mut self, alert: $crate::AlertCondition) {
459 self.$field.add_alertcondition(alert)
460 }
461 fn alertconditions(&self) -> &[$crate::AlertCondition] {
462 self.$field.alertconditions()
463 }
464 }
465
466 impl $crate::FillOutput for $type {
467 fn add_fill(&mut self, fill: $crate::FillObject) {
468 self.$field.add_fill(fill)
469 }
470 fn fills(&self) -> &[$crate::FillObject] {
471 self.$field.fills()
472 }
473 }
474
475 impl $crate::GlobalOutput for $type {
476 fn set_bgcolor(&mut self, color: Option<$crate::Color>) {
477 self.$field.set_bgcolor(color)
478 }
479 fn set_barcolor(&mut self, color: Option<$crate::Color>) {
480 self.$field.set_barcolor(color)
481 }
482 fn global_context(&self) -> &$crate::GlobalContext {
483 self.$field.global_context()
484 }
485 }
486
487 impl $crate::LineOutput for $type {
488 fn add_line(&mut self, line: $crate::LineObject) -> usize {
489 self.$field.add_line(line)
490 }
491 fn get_line(&self, id: usize) -> Option<&$crate::LineObject> {
492 self.$field.get_line(id)
493 }
494 fn get_line_mut(&mut self, id: usize) -> Option<&mut $crate::LineObject> {
495 self.$field.get_line_mut(id)
496 }
497 fn delete_line(&mut self, id: usize) -> bool {
498 self.$field.delete_line(id)
499 }
500 }
501
502 impl $crate::DrawingOutput for $type {
503 fn add_linefill(&mut self, linefill: $crate::LinefillObject) -> usize {
504 self.$field.add_linefill(linefill)
505 }
506 fn get_linefill(&self, id: usize) -> Option<&$crate::LinefillObject> {
507 self.$field.get_linefill(id)
508 }
509 fn get_linefill_mut(&mut self, id: usize) -> Option<&mut $crate::LinefillObject> {
510 self.$field.get_linefill_mut(id)
511 }
512 fn delete_linefill(&mut self, id: usize) -> bool {
513 self.$field.delete_linefill(id)
514 }
515 fn add_polyline(&mut self, polyline: $crate::PolylineObject) -> usize {
516 self.$field.add_polyline(polyline)
517 }
518 fn delete_polyline(&mut self, id: usize) -> bool {
519 self.$field.delete_polyline(id)
520 }
521 }
522
523 impl $crate::TableOutput for $type {
524 fn add_table(&mut self, table: $crate::Table) -> usize {
525 self.$field.add_table(table)
526 }
527 fn get_table(&self, id: usize) -> Option<&$crate::Table> {
528 self.$field.get_table(id)
529 }
530 fn get_table_mut(&mut self, id: usize) -> Option<&mut $crate::Table> {
531 self.$field.get_table_mut(id)
532 }
533 fn delete_table(&mut self, id: usize) -> bool {
534 self.$field.delete_table(id)
535 }
536 }
537 };
538}
539
540pub trait PlotOutput: PineOutput {
542 fn add_plot(&mut self, plot: Plot);
544 fn plots(&self) -> &[Plot];
546
547 fn add_plotarrow(&mut self, arrow: Plotarrow);
549 fn plotarrows(&self) -> &[Plotarrow];
551
552 fn add_plotbar(&mut self, bar: Plotbar);
554 fn plotbars(&self) -> &[Plotbar];
556
557 fn add_plotcandle(&mut self, candle: Plotcandle);
559 fn plotcandles(&self) -> &[Plotcandle];
561
562 fn add_plotchar(&mut self, char: Plotchar);
564 fn plotchars(&self) -> &[Plotchar];
566
567 fn add_plotshape(&mut self, shape: Plotshape);
569 fn plotshapes(&self) -> &[Plotshape];
571}
572
573pub trait LabelOutput: PineOutput {
575 fn add_label(&mut self, label: Label) -> usize;
577 fn get_label(&self, id: usize) -> Option<&Label>;
579 fn get_label_mut(&mut self, id: usize) -> Option<&mut Label>;
581 fn delete_label(&mut self, id: usize) -> bool;
583}
584
585pub trait BoxOutput: PineOutput {
587 fn add_box(&mut self, box_obj: PineBox) -> usize;
589 fn get_box(&self, id: usize) -> Option<&PineBox>;
591 fn get_box_mut(&mut self, id: usize) -> Option<&mut PineBox>;
593 fn delete_box(&mut self, id: usize) -> bool;
595}
596
597pub trait TableOutput: PineOutput {
599 fn add_table(&mut self, table: Table) -> usize;
601 fn get_table(&self, id: usize) -> Option<&Table>;
603 fn get_table_mut(&mut self, id: usize) -> Option<&mut Table>;
605 fn delete_table(&mut self, id: usize) -> bool;
607}
608
609pub trait LineOutput: PineOutput {
611 fn add_line(&mut self, line: LineObject) -> usize;
613 fn get_line(&self, id: usize) -> Option<&LineObject>;
615 fn get_line_mut(&mut self, id: usize) -> Option<&mut LineObject>;
617 fn delete_line(&mut self, id: usize) -> bool;
619}
620
621#[derive(Clone, Debug)]
623pub struct LinefillObject {
624 pub line1: usize,
625 pub line2: usize,
626 pub color: Option<Color>,
627}
628
629#[derive(Clone, Debug, Default)]
631pub struct PolylineObject {
632 pub points: Vec<(f64, f64)>,
634 pub curved: bool,
635 pub closed: bool,
636 pub xloc: String,
637 pub line_color: Option<Color>,
638 pub fill_color: Option<Color>,
639 pub line_style: String,
640 pub line_width: f64,
641}
642
643pub trait DrawingOutput: PineOutput {
646 fn add_linefill(&mut self, linefill: LinefillObject) -> usize;
647 fn get_linefill(&self, id: usize) -> Option<&LinefillObject>;
648 fn get_linefill_mut(&mut self, id: usize) -> Option<&mut LinefillObject>;
649 fn delete_linefill(&mut self, id: usize) -> bool;
650 fn add_polyline(&mut self, polyline: PolylineObject) -> usize;
651 fn delete_polyline(&mut self, id: usize) -> bool;
652}
653
654pub trait FillOutput: PineOutput {
656 fn add_fill(&mut self, fill: FillObject);
657 fn fills(&self) -> &[FillObject];
658}
659
660pub trait GlobalOutput: PineOutput {
662 fn set_bgcolor(&mut self, color: Option<Color>);
663 fn set_barcolor(&mut self, color: Option<Color>);
664 fn global_context(&self) -> &GlobalContext;
666}
667
668pub trait AlertConditionOutput: PineOutput {
670 fn add_alertcondition(&mut self, alert: AlertCondition);
672 fn alertconditions(&self) -> &[AlertCondition];
674}
675
676pub trait MetadataOutput: PineOutput {
679 fn set_indicator(&mut self, indicator: Indicator);
681 fn indicator(&self) -> Option<&Indicator>;
683 fn set_library(&mut self, library: Library);
685 fn library(&self) -> Option<&Library>;
687}
688
689pub trait InputOutput: PineOutput {
691 fn add_input(&mut self, input: Input);
693 fn inputs(&self) -> &[Input];
695}
696
697#[derive(Default, Clone, Debug)]
699pub struct DefaultPineOutput {
700 labels: HashMap<usize, Label>,
702 next_label_id: usize,
704 boxes: HashMap<usize, PineBox>,
706 next_box_id: usize,
708 lines: HashMap<usize, LineObject>,
710 next_line_id: usize,
712 tables: HashMap<usize, Table>,
714 next_table_id: usize,
716 plots: Vec<Plot>,
718 plotarrows: Vec<Plotarrow>,
720 plotbars: Vec<Plotbar>,
722 plotcandles: Vec<Plotcandle>,
724 plotchars: Vec<Plotchar>,
726 plotshapes: Vec<Plotshape>,
728 logs: Vec<LogEntry>,
730 inputs: Vec<Input>,
732 indicator: Option<Indicator>,
734 library: Option<Library>,
736 globals: GlobalContext,
738 alertconditions: Vec<AlertCondition>,
740 fills: Vec<FillObject>,
742 linefills: HashMap<usize, LinefillObject>,
744 next_linefill_id: usize,
746 polylines: HashMap<usize, PolylineObject>,
748 next_polyline_id: usize,
750}
751
752impl PineOutput for DefaultPineOutput {
753 fn clear(&mut self) {
754 self.labels.clear();
755 self.boxes.clear();
756 self.plots.clear();
757 self.plotarrows.clear();
758 self.plotbars.clear();
759 self.plotcandles.clear();
760 self.plotchars.clear();
761 self.plotshapes.clear();
762 self.logs.clear();
763 self.inputs.clear();
764 self.indicator = None;
765 self.globals = GlobalContext::default();
766 self.alertconditions.clear();
767 self.fills.clear();
768 self.lines.clear();
769 self.tables.clear();
770 self.next_label_id = 0;
772 self.next_box_id = 0;
773 self.next_line_id = 0;
774 self.next_table_id = 0;
775 }
776}
777
778impl LogOutput for DefaultPineOutput {
779 fn add_log(&mut self, level: LogLevel, message: String) {
780 self.logs.push(LogEntry { level, message });
781 }
782
783 fn get_logs(&self) -> &[LogEntry] {
784 &self.logs
785 }
786}
787
788impl PlotOutput for DefaultPineOutput {
789 fn add_plot(&mut self, plot: Plot) {
790 self.plots.push(plot);
791 }
792
793 fn plots(&self) -> &[Plot] {
794 &self.plots
795 }
796
797 fn add_plotarrow(&mut self, arrow: Plotarrow) {
798 self.plotarrows.push(arrow);
799 }
800
801 fn plotarrows(&self) -> &[Plotarrow] {
802 &self.plotarrows
803 }
804
805 fn add_plotbar(&mut self, bar: Plotbar) {
806 self.plotbars.push(bar);
807 }
808
809 fn plotbars(&self) -> &[Plotbar] {
810 &self.plotbars
811 }
812
813 fn add_plotcandle(&mut self, candle: Plotcandle) {
814 self.plotcandles.push(candle);
815 }
816
817 fn plotcandles(&self) -> &[Plotcandle] {
818 &self.plotcandles
819 }
820
821 fn add_plotchar(&mut self, char: Plotchar) {
822 self.plotchars.push(char);
823 }
824
825 fn plotchars(&self) -> &[Plotchar] {
826 &self.plotchars
827 }
828
829 fn add_plotshape(&mut self, shape: Plotshape) {
830 self.plotshapes.push(shape);
831 }
832
833 fn plotshapes(&self) -> &[Plotshape] {
834 &self.plotshapes
835 }
836}
837
838impl LabelOutput for DefaultPineOutput {
839 fn add_label(&mut self, label: Label) -> usize {
840 let id = self.next_label_id;
841 self.next_label_id += 1;
842 self.labels.insert(id, label);
843 id
844 }
845
846 fn get_label(&self, id: usize) -> Option<&Label> {
847 self.labels.get(&id)
848 }
849
850 fn get_label_mut(&mut self, id: usize) -> Option<&mut Label> {
851 self.labels.get_mut(&id)
852 }
853
854 fn delete_label(&mut self, id: usize) -> bool {
855 self.labels.remove(&id).is_some()
856 }
857}
858
859impl BoxOutput for DefaultPineOutput {
860 fn add_box(&mut self, box_obj: PineBox) -> usize {
861 let id = self.next_box_id;
862 self.next_box_id += 1;
863 self.boxes.insert(id, box_obj);
864 id
865 }
866
867 fn get_box(&self, id: usize) -> Option<&PineBox> {
868 self.boxes.get(&id)
869 }
870
871 fn get_box_mut(&mut self, id: usize) -> Option<&mut PineBox> {
872 self.boxes.get_mut(&id)
873 }
874
875 fn delete_box(&mut self, id: usize) -> bool {
876 self.boxes.remove(&id).is_some()
877 }
878}
879
880impl LineOutput for DefaultPineOutput {
881 fn add_line(&mut self, line: LineObject) -> usize {
882 let id = self.next_line_id;
883 self.next_line_id += 1;
884 self.lines.insert(id, line);
885 id
886 }
887
888 fn get_line(&self, id: usize) -> Option<&LineObject> {
889 self.lines.get(&id)
890 }
891
892 fn get_line_mut(&mut self, id: usize) -> Option<&mut LineObject> {
893 self.lines.get_mut(&id)
894 }
895
896 fn delete_line(&mut self, id: usize) -> bool {
897 self.lines.remove(&id).is_some()
898 }
899}
900
901impl DrawingOutput for DefaultPineOutput {
902 fn add_linefill(&mut self, linefill: LinefillObject) -> usize {
903 let id = self.next_linefill_id;
904 self.next_linefill_id += 1;
905 self.linefills.insert(id, linefill);
906 id
907 }
908
909 fn get_linefill(&self, id: usize) -> Option<&LinefillObject> {
910 self.linefills.get(&id)
911 }
912
913 fn get_linefill_mut(&mut self, id: usize) -> Option<&mut LinefillObject> {
914 self.linefills.get_mut(&id)
915 }
916
917 fn delete_linefill(&mut self, id: usize) -> bool {
918 self.linefills.remove(&id).is_some()
919 }
920
921 fn add_polyline(&mut self, polyline: PolylineObject) -> usize {
922 let id = self.next_polyline_id;
923 self.next_polyline_id += 1;
924 self.polylines.insert(id, polyline);
925 id
926 }
927
928 fn delete_polyline(&mut self, id: usize) -> bool {
929 self.polylines.remove(&id).is_some()
930 }
931}
932
933impl TableOutput for DefaultPineOutput {
934 fn add_table(&mut self, table: Table) -> usize {
935 let id = self.next_table_id;
936 self.next_table_id += 1;
937 self.tables.insert(id, table);
938 id
939 }
940
941 fn get_table(&self, id: usize) -> Option<&Table> {
942 self.tables.get(&id)
943 }
944
945 fn get_table_mut(&mut self, id: usize) -> Option<&mut Table> {
946 self.tables.get_mut(&id)
947 }
948
949 fn delete_table(&mut self, id: usize) -> bool {
950 self.tables.remove(&id).is_some()
951 }
952}
953
954impl InputOutput for DefaultPineOutput {
955 fn add_input(&mut self, input: Input) {
956 self.inputs.push(input);
957 }
958
959 fn inputs(&self) -> &[Input] {
960 &self.inputs
961 }
962}
963
964impl MetadataOutput for DefaultPineOutput {
965 fn set_indicator(&mut self, indicator: Indicator) {
966 self.indicator = Some(indicator);
967 }
968
969 fn indicator(&self) -> Option<&Indicator> {
970 self.indicator.as_ref()
971 }
972
973 fn set_library(&mut self, library: Library) {
974 self.library = Some(library);
975 }
976
977 fn library(&self) -> Option<&Library> {
978 self.library.as_ref()
979 }
980}
981
982impl AlertConditionOutput for DefaultPineOutput {
983 fn add_alertcondition(&mut self, alert: AlertCondition) {
984 self.alertconditions.push(alert);
985 }
986
987 fn alertconditions(&self) -> &[AlertCondition] {
988 &self.alertconditions
989 }
990}
991
992impl FillOutput for DefaultPineOutput {
993 fn add_fill(&mut self, fill: FillObject) {
994 self.fills.push(fill);
995 }
996
997 fn fills(&self) -> &[FillObject] {
998 &self.fills
999 }
1000}
1001
1002impl GlobalOutput for DefaultPineOutput {
1003 fn set_bgcolor(&mut self, color: Option<Color>) {
1004 self.globals.bgcolor = color;
1005 }
1006
1007 fn set_barcolor(&mut self, color: Option<Color>) {
1008 self.globals.barcolor = color;
1009 }
1010
1011 fn global_context(&self) -> &GlobalContext {
1012 &self.globals
1013 }
1014}