@@ -118,7 +118,7 @@ use std::ops::Range;
118
118
pub struct Resource < S > {
119
119
pub body : Vec < Entry < S > > ,
120
120
#[ cfg( feature = "spans" ) ]
121
- pub span : Range < usize > ,
121
+ pub span : Span ,
122
122
}
123
123
124
124
/// A top-level node representing an entry of a [`Resource`].
@@ -209,7 +209,7 @@ pub enum Entry<S> {
209
209
Junk {
210
210
content : S ,
211
211
#[ cfg( feature = "spans" ) ]
212
- span : Range < usize > ,
212
+ span : Span ,
213
213
} ,
214
214
}
215
215
@@ -269,7 +269,7 @@ pub struct Message<S> {
269
269
pub attributes : Vec < Attribute < S > > ,
270
270
pub comment : Option < Comment < S > > ,
271
271
#[ cfg( feature = "spans" ) ]
272
- pub span : Range < usize > ,
272
+ pub span : Span ,
273
273
}
274
274
275
275
/// A Fluent [`Term`].
@@ -325,7 +325,7 @@ pub struct Term<S> {
325
325
pub attributes : Vec < Attribute < S > > ,
326
326
pub comment : Option < Comment < S > > ,
327
327
#[ cfg( feature = "spans" ) ]
328
- pub span : Range < usize > ,
328
+ pub span : Span ,
329
329
}
330
330
331
331
/// Pattern contains a value of a [`Message`], [`Term`] or an [`Attribute`].
@@ -404,7 +404,7 @@ pub struct Term<S> {
404
404
pub struct Pattern < S > {
405
405
pub elements : Vec < PatternElement < S > > ,
406
406
#[ cfg( feature = "spans" ) ]
407
- pub span : Range < usize > ,
407
+ pub span : Span ,
408
408
}
409
409
410
410
/// `PatternElement` is an element of a [`Pattern`].
@@ -485,12 +485,12 @@ pub enum PatternElement<S> {
485
485
TextElement {
486
486
value : S ,
487
487
#[ cfg( feature = "spans" ) ]
488
- span : Range < usize > ,
488
+ span : Span ,
489
489
} ,
490
490
Placeable {
491
491
expression : Expression < S > ,
492
492
#[ cfg( feature = "spans" ) ]
493
- span : Range < usize > ,
493
+ span : Span ,
494
494
} ,
495
495
}
496
496
@@ -563,7 +563,7 @@ pub struct Attribute<S> {
563
563
pub id : Identifier < S > ,
564
564
pub value : Pattern < S > ,
565
565
#[ cfg( feature = "spans" ) ]
566
- pub span : Range < usize > ,
566
+ pub span : Span ,
567
567
}
568
568
569
569
/// Identifier is part of nodes such as [`Message`], [`Term`] and [`Attribute`].
@@ -613,7 +613,7 @@ pub struct Attribute<S> {
613
613
pub struct Identifier < S > {
614
614
pub name : S ,
615
615
#[ cfg( feature = "spans" ) ]
616
- pub span : Range < usize > ,
616
+ pub span : Span ,
617
617
}
618
618
619
619
/// Variant is a single branch of a value in a [`Select`](Expression::Select) expression.
@@ -701,7 +701,7 @@ pub struct Variant<S> {
701
701
pub value : Pattern < S > ,
702
702
pub default : bool ,
703
703
#[ cfg( feature = "spans" ) ]
704
- pub span : Range < usize > ,
704
+ pub span : Span ,
705
705
}
706
706
707
707
/// A key of a [`Variant`].
@@ -832,7 +832,7 @@ pub enum VariantKey<S> {
832
832
pub struct Comment < S > {
833
833
pub content : Vec < S > ,
834
834
#[ cfg( feature = "spans" ) ]
835
- pub span : Range < usize > ,
835
+ pub span : Span ,
836
836
}
837
837
838
838
/// List of arguments for a [`FunctionReference`](InlineExpression::FunctionReference) or a
@@ -916,7 +916,7 @@ pub struct CallArguments<S> {
916
916
pub positional : Vec < InlineExpression < S > > ,
917
917
pub named : Vec < NamedArgument < S > > ,
918
918
#[ cfg( feature = "spans" ) ]
919
- pub span : Range < usize > ,
919
+ pub span : Span ,
920
920
}
921
921
922
922
/// A key-value pair used in [`CallArguments`].
@@ -987,7 +987,7 @@ pub struct NamedArgument<S> {
987
987
pub name : Identifier < S > ,
988
988
pub value : InlineExpression < S > ,
989
989
#[ cfg( feature = "spans" ) ]
990
- pub span : Range < usize > ,
990
+ pub span : Span ,
991
991
}
992
992
993
993
/// A subset of expressions which can be used as [`Placeable`](PatternElement::Placeable),
@@ -1091,7 +1091,7 @@ pub enum InlineExpression<S> {
1091
1091
StringLiteral {
1092
1092
value : S ,
1093
1093
#[ cfg( feature = "spans" ) ]
1094
- span : Range < usize > ,
1094
+ span : Span ,
1095
1095
} ,
1096
1096
/// A number literal.
1097
1097
///
@@ -1141,7 +1141,7 @@ pub enum InlineExpression<S> {
1141
1141
NumberLiteral {
1142
1142
value : S ,
1143
1143
#[ cfg( feature = "spans" ) ]
1144
- span : Range < usize > ,
1144
+ span : Span ,
1145
1145
} ,
1146
1146
/// A function reference.
1147
1147
///
@@ -1195,7 +1195,7 @@ pub enum InlineExpression<S> {
1195
1195
id : Identifier < S > ,
1196
1196
arguments : CallArguments < S > ,
1197
1197
#[ cfg( feature = "spans" ) ]
1198
- span : Range < usize > ,
1198
+ span : Span ,
1199
1199
} ,
1200
1200
/// A reference to another message.
1201
1201
///
@@ -1249,7 +1249,7 @@ pub enum InlineExpression<S> {
1249
1249
id : Identifier < S > ,
1250
1250
attribute : Option < Identifier < S > > ,
1251
1251
#[ cfg( feature = "spans" ) ]
1252
- span : Range < usize > ,
1252
+ span : Span ,
1253
1253
} ,
1254
1254
/// A reference to a term.
1255
1255
///
@@ -1305,7 +1305,7 @@ pub enum InlineExpression<S> {
1305
1305
attribute : Option < Identifier < S > > ,
1306
1306
arguments : Option < CallArguments < S > > ,
1307
1307
#[ cfg( feature = "spans" ) ]
1308
- span : Range < usize > ,
1308
+ span : Span ,
1309
1309
} ,
1310
1310
/// A reference to a variable.
1311
1311
///
@@ -1357,7 +1357,7 @@ pub enum InlineExpression<S> {
1357
1357
VariableReference {
1358
1358
id : Identifier < S > ,
1359
1359
#[ cfg( feature = "spans" ) ]
1360
- span : Range < usize > ,
1360
+ span : Span ,
1361
1361
} ,
1362
1362
/// A placeable which may contain another expression.
1363
1363
///
@@ -1413,21 +1413,21 @@ pub enum InlineExpression<S> {
1413
1413
Placeable {
1414
1414
expression : Box < Expression < S > > ,
1415
1415
#[ cfg( feature = "spans" ) ]
1416
- span : Range < usize > ,
1416
+ span : Span ,
1417
1417
} ,
1418
1418
}
1419
1419
1420
1420
#[ cfg( feature = "spans" ) ]
1421
1421
impl < S > InlineExpression < S > {
1422
- pub fn get_span ( & self ) -> Range < usize > {
1422
+ pub fn get_span ( & self ) -> Span {
1423
1423
match self {
1424
1424
InlineExpression :: StringLiteral { span, .. }
1425
1425
| InlineExpression :: TermReference { span, .. }
1426
1426
| InlineExpression :: VariableReference { span, .. }
1427
1427
| InlineExpression :: Placeable { span, .. }
1428
1428
| InlineExpression :: NumberLiteral { span, .. }
1429
1429
| InlineExpression :: FunctionReference { span, .. }
1430
- | InlineExpression :: MessageReference { span, .. } => span. clone ( ) , // Why doesn't std::ops::Range implement the Copy trait...?
1430
+ | InlineExpression :: MessageReference { span, .. } => * span,
1431
1431
}
1432
1432
}
1433
1433
}
@@ -1521,13 +1521,49 @@ pub enum Expression<S> {
1521
1521
selector : InlineExpression < S > ,
1522
1522
variants : Vec < Variant < S > > ,
1523
1523
#[ cfg( feature = "spans" ) ]
1524
- span : Range < usize > ,
1524
+ span : Span ,
1525
1525
} ,
1526
1526
1527
1527
/// An inline expression such as `${ username }`:
1528
1528
///
1529
1529
/// ```ftl
1530
1530
/// hello-user = Hello ${ username }
1531
1531
/// ```
1532
- Inline ( InlineExpression < S > , #[ cfg( feature = "spans" ) ] Range < usize > ) ,
1532
+ Inline ( InlineExpression < S > , #[ cfg( feature = "spans" ) ] Span ) ,
1533
+ }
1534
+
1535
+ /// A span of a node. Allows you to get the index of the start and end character of a node.
1536
+ ///
1537
+ /// # Example
1538
+ ///
1539
+ /// ```
1540
+ /// #![cfg(feature = "spans")]
1541
+ ///
1542
+ /// use fluent_syntax::parser;
1543
+ /// use fluent_syntax::ast::*;
1544
+ ///
1545
+ /// let ftl = "hello-world = Hello, World!";
1546
+ ///
1547
+ /// let resource = parser::parse(ftl).expect("Failed to parse an FTL resource.");
1548
+ /// let Entry::Message(Message { ref id, .. }) = resource.body[0] else { unreachable!() };
1549
+ ///
1550
+ /// assert_eq!(resource.span, Span { start: 0, end: 27 });
1551
+ /// assert_eq!(id.span, Span { start: 0, end: 11 }); // the span of hello-world identifier
1552
+ /// ```
1553
+ #[ cfg( feature = "spans" ) ]
1554
+ #[ derive( Debug , Clone , Copy , Default , PartialEq ) ]
1555
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1556
+ pub struct Span {
1557
+ pub start : usize ,
1558
+ pub end : usize ,
1559
+ }
1560
+
1561
+ #[ cfg( feature = "spans" ) ]
1562
+ impl Span {
1563
+ pub fn new ( range : Range < usize > ) -> Self {
1564
+ Self {
1565
+ start : range. start ,
1566
+ end : range. end ,
1567
+ }
1568
+ }
1533
1569
}
0 commit comments