@@ -428,6 +428,15 @@ impl CstNode {
428
428
}
429
429
}
430
430
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
+
431
440
/// Node if it's the root node.
432
441
pub fn as_root_node ( & self ) -> Option < CstRootNode > {
433
442
match self {
@@ -1138,7 +1147,7 @@ impl CstRootNode {
1138
1147
) ;
1139
1148
}
1140
1149
1141
- /// Gets the value if its an object.
1150
+ /// Gets the root value if its an object.
1142
1151
pub fn object_value ( & self ) -> Option < CstObject > {
1143
1152
self . value ( ) ?. as_object ( )
1144
1153
}
@@ -1159,7 +1168,7 @@ impl CstRootNode {
1159
1168
}
1160
1169
}
1161
1170
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.
1163
1172
///
1164
1173
/// Note: Use `.object_value_or_create()` to not overwrite the root value
1165
1174
/// when it's not an object.
@@ -1194,7 +1203,7 @@ impl CstRootNode {
1194
1203
}
1195
1204
}
1196
1205
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.
1198
1207
///
1199
1208
/// Note: Use `.array_value_or_create()` to not overwrite the root value
1200
1209
/// when it's not an object.
@@ -1608,22 +1617,28 @@ impl CstObject {
1608
1617
}
1609
1618
1610
1619
/// 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)
1613
1624
}
1614
1625
1615
1626
/// 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)
1618
1631
}
1619
1632
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 {
1621
1634
insert_or_append_to_container (
1622
1635
& CstContainerNode :: Object ( self . clone ( ) ) ,
1623
1636
self . properties ( ) . into_iter ( ) . map ( |c| c. into ( ) ) . collect ( ) ,
1624
1637
index,
1625
1638
InsertValue :: Property ( prop_name, value) ,
1626
1639
)
1640
+ . as_object_prop ( )
1641
+ . unwrap ( )
1627
1642
}
1628
1643
1629
1644
/// Replaces this node with a new value.
@@ -1691,6 +1706,18 @@ impl CstObjectProp {
1691
1706
None
1692
1707
}
1693
1708
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
+
1694
1721
pub fn set_value ( & self , replacement : CstInputValue ) {
1695
1722
let maybe_value = self . value ( ) ;
1696
1723
let mut value_index = maybe_value
@@ -1753,6 +1780,38 @@ impl CstObjectProp {
1753
1780
None
1754
1781
}
1755
1782
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
+
1756
1815
/// Sibling object property coming before this one.
1757
1816
pub fn previous_property ( & self ) -> Option < CstObjectProp > {
1758
1817
for sibling in self . previous_siblings ( ) {
@@ -1892,13 +1951,17 @@ impl CstArray {
1892
1951
}
1893
1952
1894
1953
/// 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)
1897
1958
}
1898
1959
1899
1960
/// 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)
1902
1965
}
1903
1966
1904
1967
/// Ensures the array spans multiple lines.
@@ -1911,7 +1974,7 @@ impl CstArray {
1911
1974
set_trailing_commas ( mode, & self . clone ( ) . into ( ) , self . elements ( ) . into_iter ( ) ) ;
1912
1975
}
1913
1976
1914
- fn insert_or_append ( & self , index : Option < usize > , value : CstInputValue ) {
1977
+ fn insert_or_append ( & self , index : Option < usize > , value : CstInputValue ) -> CstNode {
1915
1978
insert_or_append_to_container (
1916
1979
& CstContainerNode :: Array ( self . clone ( ) ) ,
1917
1980
self . elements ( ) ,
@@ -2481,7 +2544,7 @@ fn insert_or_append_to_container(
2481
2544
elements : Vec < CstNode > ,
2482
2545
index : Option < usize > ,
2483
2546
value : InsertValue ,
2484
- ) {
2547
+ ) -> CstNode {
2485
2548
fn has_separating_newline ( siblings : impl Iterator < Item = CstNode > ) -> bool {
2486
2549
for sibling in siblings {
2487
2550
if sibling. is_newline ( ) {
@@ -2518,6 +2581,7 @@ fn insert_or_append_to_container(
2518
2581
InsertValue :: Property ( ..) => true ,
2519
2582
} ;
2520
2583
let mut insert_index: usize ;
2584
+ let inserted_node: CstNode ;
2521
2585
if let Some ( previous_node) = previous_node {
2522
2586
if previous_node. trailing_comma ( ) . is_none ( ) {
2523
2587
let mut index = previous_node. child_index ( ) + 1 ;
@@ -2540,9 +2604,11 @@ fn insert_or_append_to_container(
2540
2604
] ,
2541
2605
) ;
2542
2606
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 ( ) ;
2543
2608
} else {
2544
2609
container. raw_insert_child ( Some ( & mut insert_index) , CstWhitespace :: new ( " " . to_string ( ) ) . into ( ) ) ;
2545
2610
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 ( ) ;
2546
2612
}
2547
2613
} else {
2548
2614
insert_index = if elements. is_empty ( ) {
@@ -2566,6 +2632,7 @@ fn insert_or_append_to_container(
2566
2632
] ,
2567
2633
) ;
2568
2634
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 ( ) ;
2569
2636
if next_node. is_none ( )
2570
2637
&& !has_separating_newline ( container. child_at_index ( insert_index - 1 ) . unwrap ( ) . next_siblings ( ) )
2571
2638
{
@@ -2579,6 +2646,7 @@ fn insert_or_append_to_container(
2579
2646
}
2580
2647
} else {
2581
2648
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 ( ) ;
2582
2650
}
2583
2651
}
2584
2652
@@ -2602,6 +2670,8 @@ fn insert_or_append_to_container(
2602
2670
} else if style_info. uses_trailing_commas && force_multiline {
2603
2671
container. raw_insert_children ( Some ( & mut insert_index) , vec ! [ CstToken :: new( ',' ) . into( ) ] ) ;
2604
2672
}
2673
+
2674
+ inserted_node
2605
2675
}
2606
2676
2607
2677
fn set_trailing_commas (
@@ -3682,6 +3752,15 @@ value3: true
3682
3752
let value = object. object_value_or_set ( "test" ) ;
3683
3753
assert_eq ! ( value. to_string( ) , "{}" ) ;
3684
3754
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 " ) ;
3685
3764
}
3686
3765
3687
3766
#[ test]
@@ -3730,6 +3809,24 @@ value3: true
3730
3809
)
3731
3810
}
3732
3811
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
+
3733
3830
fn build_cst ( text : & str ) -> CstRootNode {
3734
3831
CstRootNode :: parse ( text, & crate :: ParseOptions :: default ( ) ) . unwrap ( )
3735
3832
}
0 commit comments