Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c0d54c8

Browse files
authored
feat(cst): insert into object or array returning get node (#47)
1 parent 800c087 commit c0d54c8

File tree

1 file changed

+111
-14
lines changed

1 file changed

+111
-14
lines changed

src/cst/mod.rs

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,15 @@ impl CstNode {
428428
}
429429
}
430430

431+
/// Gets the array element index of this node if its parent is an array.
432+
///
433+
/// Returns `None` when the parent is not an array.
434+
pub fn element_index(&self) -> Option<usize> {
435+
let child_index = self.child_index();
436+
let array = self.parent()?.as_array()?;
437+
array.elements().iter().position(|p| p.child_index() == child_index)
438+
}
439+
431440
/// Node if it's the root node.
432441
pub fn as_root_node(&self) -> Option<CstRootNode> {
433442
match self {
@@ -1138,7 +1147,7 @@ impl CstRootNode {
11381147
);
11391148
}
11401149

1141-
/// Gets the value if its an object.
1150+
/// Gets the root value if its an object.
11421151
pub fn object_value(&self) -> Option<CstObject> {
11431152
self.value()?.as_object()
11441153
}
@@ -1159,7 +1168,7 @@ impl CstRootNode {
11591168
}
11601169
}
11611170

1162-
/// Gets the value if it's an object or sets the root value as an object.
1171+
/// Gets the root value if it's an object or sets the root value as an object.
11631172
///
11641173
/// Note: Use `.object_value_or_create()` to not overwrite the root value
11651174
/// when it's not an object.
@@ -1194,7 +1203,7 @@ impl CstRootNode {
11941203
}
11951204
}
11961205

1197-
/// Gets the value if it's an object or sets the root value as an object.
1206+
/// Gets the root value if it's an object or sets the root value as an object.
11981207
///
11991208
/// Note: Use `.array_value_or_create()` to not overwrite the root value
12001209
/// when it's not an object.
@@ -1608,22 +1617,28 @@ impl CstObject {
16081617
}
16091618

16101619
/// Appends a property to the object.
1611-
pub fn append(&self, prop_name: &str, value: CstInputValue) {
1612-
self.insert_or_append(None, prop_name, value);
1620+
///
1621+
/// Returns the inserted object property.
1622+
pub fn append(&self, prop_name: &str, value: CstInputValue) -> CstObjectProp {
1623+
self.insert_or_append(None, prop_name, value)
16131624
}
16141625

16151626
/// Inserts a property at the specified index.
1616-
pub fn insert(&self, index: usize, prop_name: &str, value: CstInputValue) {
1617-
self.insert_or_append(Some(index), prop_name, value);
1627+
///
1628+
/// Returns the inserted object property.
1629+
pub fn insert(&self, index: usize, prop_name: &str, value: CstInputValue) -> CstObjectProp {
1630+
self.insert_or_append(Some(index), prop_name, value)
16181631
}
16191632

1620-
fn insert_or_append(&self, index: Option<usize>, prop_name: &str, value: CstInputValue) {
1633+
fn insert_or_append(&self, index: Option<usize>, prop_name: &str, value: CstInputValue) -> CstObjectProp {
16211634
insert_or_append_to_container(
16221635
&CstContainerNode::Object(self.clone()),
16231636
self.properties().into_iter().map(|c| c.into()).collect(),
16241637
index,
16251638
InsertValue::Property(prop_name, value),
16261639
)
1640+
.as_object_prop()
1641+
.unwrap()
16271642
}
16281643

16291644
/// Replaces this node with a new value.
@@ -1691,6 +1706,18 @@ impl CstObjectProp {
16911706
None
16921707
}
16931708

1709+
pub fn property_index(&self) -> usize {
1710+
let child_index = self.child_index();
1711+
let Some(parent) = self.parent().and_then(|p| p.as_object()) else {
1712+
return 0;
1713+
};
1714+
parent
1715+
.properties()
1716+
.iter()
1717+
.position(|p| p.child_index() == child_index)
1718+
.unwrap_or(0)
1719+
}
1720+
16941721
pub fn set_value(&self, replacement: CstInputValue) {
16951722
let maybe_value = self.value();
16961723
let mut value_index = maybe_value
@@ -1753,6 +1780,38 @@ impl CstObjectProp {
17531780
None
17541781
}
17551782

1783+
/// Gets the value if its an object.
1784+
pub fn object_value(&self) -> Option<CstObject> {
1785+
self.value()?.as_object()
1786+
}
1787+
1788+
/// Gets the value if it's an object or sets the value as an object.
1789+
pub fn object_value_or_set(&self) -> CstObject {
1790+
match self.value() {
1791+
Some(CstNode::Container(CstContainerNode::Object(node))) => node,
1792+
_ => {
1793+
self.set_value(CstInputValue::Object(Vec::new()));
1794+
self.object_value().unwrap()
1795+
}
1796+
}
1797+
}
1798+
1799+
/// Gets the value if its an array.
1800+
pub fn array_value(&self) -> Option<CstArray> {
1801+
self.value()?.as_array()
1802+
}
1803+
1804+
/// Gets the value if it's an object or sets the value as an object.
1805+
pub fn array_value_or_set(&self) -> CstArray {
1806+
match self.value() {
1807+
Some(CstNode::Container(CstContainerNode::Array(node))) => node,
1808+
_ => {
1809+
self.set_value(CstInputValue::Array(Vec::new()));
1810+
self.array_value().unwrap()
1811+
}
1812+
}
1813+
}
1814+
17561815
/// Sibling object property coming before this one.
17571816
pub fn previous_property(&self) -> Option<CstObjectProp> {
17581817
for sibling in self.previous_siblings() {
@@ -1892,13 +1951,17 @@ impl CstArray {
18921951
}
18931952

18941953
/// Appends an element to the end of the array.
1895-
pub fn append(&self, value: CstInputValue) {
1896-
self.insert_or_append(None, value);
1954+
///
1955+
/// Returns the appended node.
1956+
pub fn append(&self, value: CstInputValue) -> CstNode {
1957+
self.insert_or_append(None, value)
18971958
}
18981959

18991960
/// Inserts an element at the specified index.
1900-
pub fn insert(&self, index: usize, value: CstInputValue) {
1901-
self.insert_or_append(Some(index), value);
1961+
///
1962+
/// Returns the inserted node.
1963+
pub fn insert(&self, index: usize, value: CstInputValue) -> CstNode {
1964+
self.insert_or_append(Some(index), value)
19021965
}
19031966

19041967
/// Ensures the array spans multiple lines.
@@ -1911,7 +1974,7 @@ impl CstArray {
19111974
set_trailing_commas(mode, &self.clone().into(), self.elements().into_iter());
19121975
}
19131976

1914-
fn insert_or_append(&self, index: Option<usize>, value: CstInputValue) {
1977+
fn insert_or_append(&self, index: Option<usize>, value: CstInputValue) -> CstNode {
19151978
insert_or_append_to_container(
19161979
&CstContainerNode::Array(self.clone()),
19171980
self.elements(),
@@ -2481,7 +2544,7 @@ fn insert_or_append_to_container(
24812544
elements: Vec<CstNode>,
24822545
index: Option<usize>,
24832546
value: InsertValue,
2484-
) {
2547+
) -> CstNode {
24852548
fn has_separating_newline(siblings: impl Iterator<Item = CstNode>) -> bool {
24862549
for sibling in siblings {
24872550
if sibling.is_newline() {
@@ -2518,6 +2581,7 @@ fn insert_or_append_to_container(
25182581
InsertValue::Property(..) => true,
25192582
};
25202583
let mut insert_index: usize;
2584+
let inserted_node: CstNode;
25212585
if let Some(previous_node) = previous_node {
25222586
if previous_node.trailing_comma().is_none() {
25232587
let mut index = previous_node.child_index() + 1;
@@ -2540,9 +2604,11 @@ fn insert_or_append_to_container(
25402604
],
25412605
);
25422606
container.raw_insert_value_with_internal_indent(Some(&mut insert_index), value, &style_info, &child_indents);
2607+
inserted_node = container.child_at_index(insert_index - 1).unwrap();
25432608
} else {
25442609
container.raw_insert_child(Some(&mut insert_index), CstWhitespace::new(" ".to_string()).into());
25452610
container.raw_insert_value_with_internal_indent(Some(&mut insert_index), value, &style_info, &child_indents);
2611+
inserted_node = container.child_at_index(insert_index - 1).unwrap();
25462612
}
25472613
} else {
25482614
insert_index = if elements.is_empty() {
@@ -2566,6 +2632,7 @@ fn insert_or_append_to_container(
25662632
],
25672633
);
25682634
container.raw_insert_value_with_internal_indent(Some(&mut insert_index), value, &style_info, &child_indents);
2635+
inserted_node = container.child_at_index(insert_index - 1).unwrap();
25692636
if next_node.is_none()
25702637
&& !has_separating_newline(container.child_at_index(insert_index - 1).unwrap().next_siblings())
25712638
{
@@ -2579,6 +2646,7 @@ fn insert_or_append_to_container(
25792646
}
25802647
} else {
25812648
container.raw_insert_value_with_internal_indent(Some(&mut insert_index), value, &style_info, &child_indents);
2649+
inserted_node = container.child_at_index(insert_index - 1).unwrap();
25822650
}
25832651
}
25842652

@@ -2602,6 +2670,8 @@ fn insert_or_append_to_container(
26022670
} else if style_info.uses_trailing_commas && force_multiline {
26032671
container.raw_insert_children(Some(&mut insert_index), vec![CstToken::new(',').into()]);
26042672
}
2673+
2674+
inserted_node
26052675
}
26062676

26072677
fn set_trailing_commas(
@@ -3682,6 +3752,15 @@ value3: true
36823752
let value = object.object_value_or_set("test");
36833753
assert_eq!(value.to_string(), "{}");
36843754
assert_eq!(cst.to_string(), "{\n \"test\": {}\n}\n");
3755+
let test_prop = object.get("test").unwrap();
3756+
assert!(test_prop.object_value().is_some());
3757+
assert!(test_prop.array_value().is_none());
3758+
test_prop.array_value_or_set();
3759+
assert_eq!(cst.to_string(), "{\n \"test\": []\n}\n");
3760+
assert!(test_prop.object_value().is_none());
3761+
assert!(test_prop.array_value().is_some());
3762+
test_prop.object_value_or_set();
3763+
assert_eq!(cst.to_string(), "{\n \"test\": {}\n}\n");
36853764
}
36863765

36873766
#[test]
@@ -3730,6 +3809,24 @@ value3: true
37303809
)
37313810
}
37323811

3812+
#[test]
3813+
fn property_index() {
3814+
let cst = build_cst("{ \"prop\": 1, \"prop2\": 2, \"prop3\": 3 }");
3815+
let object = cst.object_value().unwrap();
3816+
for (i, prop) in object.properties().into_iter().enumerate() {
3817+
assert_eq!(prop.property_index(), i);
3818+
}
3819+
}
3820+
3821+
#[test]
3822+
fn element_index() {
3823+
let cst = build_cst("[1, 2, true ,false]");
3824+
let array = cst.array_value().unwrap();
3825+
for (i, prop) in array.elements().into_iter().enumerate() {
3826+
assert_eq!(prop.element_index().unwrap(), i);
3827+
}
3828+
}
3829+
37333830
fn build_cst(text: &str) -> CstRootNode {
37343831
CstRootNode::parse(text, &crate::ParseOptions::default()).unwrap()
37353832
}

0 commit comments

Comments
 (0)