1use serde::{Deserialize, Serialize};
7
8use crate::doc_ng::{
9 block_model::{Icon, Waypoint},
10 geometry::{FracVal, GridPoint, GridRect, ScreenRect},
11 hash::AssetHash,
12 id::{BlockId, CommentId, ImageId, PinId, RouteId, RouteLabelId, TextId},
13 values::{LabelSide, PinDir, Role},
14};
15
16#[derive(Serialize, Deserialize, Debug, Clone)]
17pub enum OpCode<W, I> {
18 Create(I),
21 Set(W),
22 Delete,
24 Restore,
25}
26
27impl<W: Invert, I> OpCode<W, I> {
28 pub fn invert(self) -> Option<OpCode<W, I>> {
29 match self {
30 OpCode::Create(_) | OpCode::Restore => Some(OpCode::Delete),
31 OpCode::Set(w) => Some(OpCode::Set(w.invert())),
32 OpCode::Delete => Some(OpCode::Restore),
33 }
34 }
35}
36
37pub trait Invert {
39 #[must_use]
40 fn invert(self) -> Self;
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone)]
44pub struct Swap<T> {
45 pub old: T,
46 pub new: T,
47}
48
49impl<T> Swap<T> {
50 #[must_use]
51 pub fn invert(self) -> Self {
52 Swap {
53 old: self.new,
54 new: self.old,
55 }
56 }
57}
58
59#[derive(Serialize, Deserialize, Debug, Clone)]
64pub enum DocumentWrite {
65 Name(Swap<String>),
66}
67
68#[derive(Serialize, Deserialize, Debug, Clone)]
69pub enum LabelWrite {
70 Name(Swap<String>),
71 Side(Swap<LabelSide>),
72 Offset(Swap<FracVal>),
73 Hidden(Swap<bool>),
74}
75
76#[derive(Serialize, Deserialize, Debug, Clone)]
77pub enum BlockWrite {
78 Parent(Swap<BlockId>),
79 Rect(Swap<GridRect>),
80 Locked(Swap<bool>),
81 Title(LabelWrite),
82 TypeLabel(LabelWrite),
83 Icon(Swap<Icon>),
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone)]
87pub enum PinWrite {
88 Owner(Swap<BlockId>),
89 Name(Swap<String>),
90 TypeName(Swap<String>),
91 Tag(Swap<String>),
92 TagHidden(Swap<bool>),
93 Rect(Swap<GridRect>),
94 Dir(Swap<PinDir>),
95 PinAccent(Swap<Role>),
96 PortAccent(Swap<Role>),
97 PortPinAccent(Swap<Role>),
98 FlipLR(Swap<bool>),
99}
100
101#[derive(Serialize, Deserialize, Debug, Clone)]
102pub enum RouteWrite {
103 Owner(Swap<BlockId>),
104 Name(Swap<String>),
105 Role(Swap<Role>),
106 Waypoints(Swap<Vec<Waypoint>>),
107}
108
109#[derive(Serialize, Deserialize, Debug, Clone)]
110pub enum RouteLabelWrite {
111 Owner(Swap<RouteId>),
112 Pos(Swap<FracVal>),
113}
114
115#[derive(Serialize, Deserialize, Debug, Clone)]
116pub enum TextWrite {
117 Owner(Swap<BlockId>),
118 Text(Swap<String>),
119 Pos(Swap<GridPoint>),
120 Role(Swap<Role>),
121}
122
123#[derive(Serialize, Deserialize, Debug, Clone)]
124pub enum CommentWrite {
125 Owner(Swap<BlockId>),
126 Rect(Swap<GridRect>),
127 Role(Swap<Role>),
128 Title(LabelWrite),
129}
130
131#[derive(Serialize, Deserialize, Debug, Clone)]
132pub enum ImageWrite {
133 Owner(Swap<BlockId>),
134 Asset(Swap<AssetHash>),
135 Rect(Swap<ScreenRect>),
136}
137
138#[derive(Serialize, Deserialize, Debug, Clone)]
143pub struct LabelInit {
144 pub name: String,
145 pub side: LabelSide,
146 pub offset: FracVal,
147 pub hidden: bool,
148}
149
150#[derive(Serialize, Deserialize, Debug, Clone)]
151pub struct BlockInit {
152 pub parent: BlockId,
154 pub rect: GridRect,
155 pub locked: bool,
156 pub title: LabelInit,
157 pub type_label: LabelInit,
158 pub icon: Icon,
159}
160
161#[derive(Serialize, Deserialize, Debug, Clone)]
162pub struct PinInit {
163 pub owner: BlockId,
164 pub name: String,
165 pub type_name: String,
166 pub tag: String,
167 pub tag_hidden: bool,
168 pub rect: GridRect,
169 pub dir: PinDir,
170 pub pin_accent: Role,
171 pub port_accent: Role,
172 pub port_pin_accent: Role,
173 pub flip_lr: bool,
174}
175
176#[derive(Serialize, Deserialize, Debug, Clone)]
177pub struct RouteInit {
178 pub owner: BlockId,
179 pub name: String,
180 pub from: PinId,
181 pub to: PinId,
182 pub role: Role,
183 pub waypoints: Vec<Waypoint>,
184}
185
186#[derive(Serialize, Deserialize, Debug, Clone)]
187pub struct RouteLabelInit {
188 pub owner: RouteId,
189 pub pos: FracVal,
190}
191
192#[derive(Serialize, Deserialize, Debug, Clone)]
193pub struct TextInit {
194 pub owner: BlockId,
195 pub text: String,
196 pub pos: GridPoint,
197 pub role: Role,
198}
199
200#[derive(Serialize, Deserialize, Debug, Clone)]
201pub struct CommentInit {
202 pub owner: BlockId,
203 pub rect: GridRect,
204 pub role: Role,
205 pub title: LabelInit,
206}
207
208#[derive(Serialize, Deserialize, Debug, Clone)]
209pub struct ImageInit {
210 pub owner: BlockId,
211 pub asset: AssetHash,
212 pub rect: ScreenRect,
213}
214
215#[derive(Serialize, Deserialize, Debug, Clone)]
216pub enum Command {
217 Document(DocumentWrite),
219 Block(BlockId, OpCode<BlockWrite, BlockInit>),
220 Pin(PinId, OpCode<PinWrite, PinInit>),
221 Route(RouteId, OpCode<RouteWrite, RouteInit>),
222 RouteLabel(RouteLabelId, OpCode<RouteLabelWrite, RouteLabelInit>),
223 Text(TextId, OpCode<TextWrite, TextInit>),
224 Comment(CommentId, OpCode<CommentWrite, CommentInit>),
225 Image(ImageId, OpCode<ImageWrite, ImageInit>),
226}