geo_aid_script/unroll/library/
segment.rs1use std::fmt::Display;
4
5use crate::{
6 figure::SegmentItem,
7 math::Build,
8 parser::PropertyValue,
9 span,
10 token::StrLit,
11 unroll::{
12 figure::{MaybeUnset, Node},
13 Dummy,
14 },
15};
16
17use super::prelude::*;
18use crate::token::Span;
19use geo_aid_figure::math_string::MathString;
20
21#[derive(Debug)]
23pub struct Segment {
24 pub a: Expr<Point>,
25 pub b: Expr<Point>,
26}
27
28impl DerivedType for Segment {
29 fn as_any(&self) -> &dyn std::any::Any {
30 self
31 }
32}
33
34impl Display for Segment {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 write!(f, "Semgent({}, {})", self.a, self.b)
37 }
38}
39
40impl_derived! {Segment}
41
42#[derive(Debug)]
43struct SegmentNode {
44 display: MaybeUnset<bool>,
46 display_segment: MaybeUnset<bool>,
48 style: MaybeUnset<Style>,
50 a: Expr<Point>,
52 b: Expr<Point>,
54}
55
56impl Dummy for SegmentNode {
57 fn dummy() -> Self {
58 Self {
59 display: MaybeUnset::new(true),
60 display_segment: MaybeUnset::new(true),
61 style: MaybeUnset::new(Style::Solid),
62 a: Expr::dummy(),
63 b: Expr::dummy(),
64 }
65 }
66
67 fn is_dummy(&self) -> bool {
68 self.a.is_dummy() || self.b.is_dummy()
69 }
70}
71
72impl Node for SegmentNode {
73 fn set_display(&mut self, display: bool) {
74 self.display.set(display);
75 }
76
77 fn get_display(&self) -> bool {
78 self.display.get_copied()
79 }
80
81 fn build(self: Box<Self>, build: &mut Build) {
82 if self.display.unwrap() && !self.is_dummy() && self.display_segment.unwrap() {
83 let p_id = build.load(&self.a);
84 let q_id = build.load(&self.b);
85
86 build.add(SegmentItem {
87 p_id,
88 q_id,
89 label: MathString::new(),
90 style: self.style.get_copied(),
91 });
92 }
93 }
94}
95
96fn segment_function_point_point(
98 mut a: Expr<Point>,
99 mut b: Expr<Point>,
100 context: &CompileContext,
101 mut display: Properties,
102) -> SegmentExpr {
103 let node = SegmentNode {
104 display: display.get("display").maybe_unset(true),
105 display_segment: display.get("display_segment").maybe_unset(true),
106 style: display.get("style").maybe_unset(Style::default()),
107 a: a.clone_without_node(),
108 b: b.clone_without_node(),
109 };
110
111 display.ignore("default-label");
112 display.finish(context);
113
114 let mut node = HierarchyNode::new_dyn(node);
115 node.extend_children(a.take_node());
116 node.extend_children(b.take_node());
117
118 SegmentExpr::new(Segment { a, b }, node)
119}
120
121#[derive(Debug)]
129pub struct Associated;
130
131fn len(segment: SegmentExpr, context: &mut CompileContext, mut display: Properties) -> Distance {
133 display.add_if_not_present(
134 "display_segment",
135 (
136 Span::empty(),
137 PropertyValue::String(StrLit {
138 span: span!(0, 0, 0, 0),
139 content: String::from("false"),
140 }),
141 ),
142 );
143
144 let segment = segment.get();
145
146 if let Some(segment) = segment {
147 super::dst::distance_function_pp(
148 segment.a.clone_without_node(),
149 segment.b.clone_without_node(),
150 context,
151 display,
152 )
153 } else {
154 Distance::dummy()
155 }
156}
157
158pub fn register(library: &mut Library) {
160 library
161 .add(
162 Function::new("segment")
163 .overload(|mut col: Pc<2>, context: &CompileContext, display| {
164 segment_function_point_point(
165 index!(node col,0),
166 index!(node col,1),
167 context,
168 display,
169 )
170 })
171 .overload(segment_function_point_point),
172 )
173 .add(
174 Function::new("len")
175 .alias_method(ty::derived("Segment"), "len")
176 .overload(len),
177 );
178}