+8
CHANGELOG.md
+8
CHANGELOG.md
···
5
5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
8
+
## Unreleased
9
+
10
+
### DSL
11
+
12
+
#### Added
13
+
14
+
- Support adding an edge multiple times, or setting an attribute multiple times with the same value. Previously these would raise runtime errors.
15
+
8
16
## v0.11.1 -- 2024-03-06
9
17
10
18
Updated the `tree-sitter` dependency to include the required minimal patch version.
-1
src/execution/lazy.rs
-1
src/execution/lazy.rs
···
165
165
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
166
166
pub(super) enum GraphElementKey {
167
167
NodeAttribute(graph::GraphNodeRef, Identifier),
168
-
Edge(graph::GraphNodeRef, graph::GraphNodeRef),
169
168
EdgeAttribute(graph::GraphNodeRef, graph::GraphNodeRef, Identifier),
170
169
}
171
170
+1
-17
src/execution/lazy/statements.rs
+1
-17
src/execution/lazy/statements.rs
···
226
226
.sink
227
227
.evaluate_as_graph_node(exec)
228
228
.with_context(|| "Evaluating edge sink".to_string().into())?;
229
-
let prev_debug_info = exec
230
-
.prev_element_debug_info
231
-
.insert(GraphElementKey::Edge(source, sink), self.debug_info.clone());
232
229
let edge = match exec.graph[source].add_edge(sink) {
233
-
Ok(edge) => edge,
234
-
Err(_) => {
235
-
return Err(ExecutionError::DuplicateEdge(format!(
236
-
"({} -> {})",
237
-
source, sink,
238
-
)))
239
-
.with_context(|| {
240
-
(
241
-
prev_debug_info.unwrap().into(),
242
-
self.debug_info.clone().into(),
243
-
)
244
-
.into()
245
-
});
246
-
}
230
+
Ok(edge) | Err(edge) => edge,
247
231
};
248
232
edge.attributes = self.attributes.clone();
249
233
Ok(())
+1
-7
src/execution/strict.rs
+1
-7
src/execution/strict.rs
···
334
334
let source = self.source.evaluate(exec)?.into_graph_node_ref()?;
335
335
let sink = self.sink.evaluate(exec)?.into_graph_node_ref()?;
336
336
let edge = match exec.graph[source].add_edge(sink) {
337
-
Ok(edge) => edge,
338
-
Err(_) => {
339
-
return Err(ExecutionError::DuplicateEdge(format!(
340
-
"({} -> {}) in {}",
341
-
source, sink, self,
342
-
)))?
343
-
}
337
+
Ok(edge) | Err(edge) => edge,
344
338
};
345
339
self.add_debug_attrs(&mut edge.attributes, exec.config)?;
346
340
Ok(())
+7
-3
src/graph.rs
+7
-3
src/graph.rs
···
275
275
276
276
/// Adds an attribute to this attribute set. If there was already an attribute with the same
277
277
/// name, replaces its value and returns `Err`.
278
-
pub fn add<V: Into<Value>>(&mut self, name: Identifier, value: V) -> Result<(), ()> {
278
+
pub fn add<V: Into<Value>>(&mut self, name: Identifier, value: V) -> Result<(), Value> {
279
279
match self.values.entry(name) {
280
280
Entry::Occupied(mut o) => {
281
-
o.insert(value.into());
282
-
Err(())
281
+
let value = value.into();
282
+
if o.get() != &value {
283
+
Err(o.insert(value.into()))
284
+
} else {
285
+
Ok(())
286
+
}
283
287
}
284
288
Entry::Vacant(v) => {
285
289
v.insert(value.into());
+64
tests/it/execution.rs
+64
tests/it/execution.rs
···
1008
1008
"#},
1009
1009
);
1010
1010
}
1011
+
1012
+
#[test]
1013
+
fn can_add_edge_twice() {
1014
+
check_execution(
1015
+
indoc! { r#"
1016
+
pass
1017
+
"#},
1018
+
indoc! {r#"
1019
+
(module) {
1020
+
node n1;
1021
+
node n2;
1022
+
edge n1 -> n2;
1023
+
edge n1 -> n2;
1024
+
}
1025
+
"#},
1026
+
indoc! {r#"
1027
+
node 0
1028
+
edge 0 -> 1
1029
+
node 1
1030
+
"#},
1031
+
);
1032
+
}
1033
+
1034
+
#[test]
1035
+
fn can_set_node_attribute_value_twice() {
1036
+
check_execution(
1037
+
indoc! { r#"
1038
+
pass
1039
+
"#},
1040
+
indoc! {r#"
1041
+
(module) {
1042
+
node n;
1043
+
attr (n) foo = #true;
1044
+
}
1045
+
"#},
1046
+
indoc! {r#"
1047
+
node 0
1048
+
foo: #true
1049
+
"#},
1050
+
);
1051
+
}
1052
+
1053
+
#[test]
1054
+
fn cannot_change_attribute_value() {
1055
+
check_execution(
1056
+
indoc! { r#"
1057
+
pass
1058
+
"#},
1059
+
indoc! {r#"
1060
+
(module) {
1061
+
node n1;
1062
+
node n2;
1063
+
edge n1 -> n2;
1064
+
attr (n1 -> n2) foo = #true;
1065
+
}
1066
+
"#},
1067
+
indoc! {r#"
1068
+
node 0
1069
+
edge 0 -> 1
1070
+
foo: #true
1071
+
node 1
1072
+
"#},
1073
+
);
1074
+
}
+64
tests/it/lazy_execution.rs
+64
tests/it/lazy_execution.rs
···
1527
1527
"#},
1528
1528
);
1529
1529
}
1530
+
1531
+
#[test]
1532
+
fn can_add_edge_twice() {
1533
+
check_execution(
1534
+
indoc! { r#"
1535
+
pass
1536
+
"#},
1537
+
indoc! {r#"
1538
+
(module) {
1539
+
node n1;
1540
+
node n2;
1541
+
edge n1 -> n2;
1542
+
edge n1 -> n2;
1543
+
}
1544
+
"#},
1545
+
indoc! {r#"
1546
+
node 0
1547
+
edge 0 -> 1
1548
+
node 1
1549
+
"#},
1550
+
);
1551
+
}
1552
+
1553
+
#[test]
1554
+
fn can_set_node_attribute_value_twice() {
1555
+
check_execution(
1556
+
indoc! { r#"
1557
+
pass
1558
+
"#},
1559
+
indoc! {r#"
1560
+
(module) {
1561
+
node n;
1562
+
attr (n) foo = #true;
1563
+
}
1564
+
"#},
1565
+
indoc! {r#"
1566
+
node 0
1567
+
foo: #true
1568
+
"#},
1569
+
);
1570
+
}
1571
+
1572
+
#[test]
1573
+
fn cannot_change_attribute_value() {
1574
+
check_execution(
1575
+
indoc! { r#"
1576
+
pass
1577
+
"#},
1578
+
indoc! {r#"
1579
+
(module) {
1580
+
node n1;
1581
+
node n2;
1582
+
edge n1 -> n2;
1583
+
attr (n1 -> n2) foo = #true;
1584
+
}
1585
+
"#},
1586
+
indoc! {r#"
1587
+
node 0
1588
+
edge 0 -> 1
1589
+
foo: #true
1590
+
node 1
1591
+
"#},
1592
+
);
1593
+
}