miden_debug_types/
location.rs1use core::{fmt, ops::Range};
2
3use miden_crypto::utils::{
4 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
5};
6#[cfg(feature = "arbitrary")]
7use proptest::prelude::*;
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11use super::{
12 ByteIndex, Uri,
13 source_file::{ColumnNumber, LineNumber},
14};
15
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
18#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
19#[cfg_attr(all(feature = "arbitrary", test), miden_test_serde_macros::serde_test)]
20pub struct Location {
21 pub uri: Uri,
23 pub start: ByteIndex,
25 pub end: ByteIndex,
27}
28
29impl Location {
30 pub const fn new(uri: Uri, start: ByteIndex, end: ByteIndex) -> Self {
32 Self { uri, start, end }
33 }
34
35 pub fn uri(&self) -> &Uri {
37 &self.uri
38 }
39
40 pub const fn range(&self) -> Range<ByteIndex> {
42 self.start..self.end
43 }
44}
45
46impl Serializable for Location {
47 fn write_into<W: ByteWriter>(&self, target: &mut W) {
48 self.uri.write_into(target);
49 self.start.to_u32().write_into(target);
50 self.end.to_u32().write_into(target);
51 }
52}
53
54impl Deserializable for Location {
55 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
56 let uri = Uri::read_from(source)?;
57 let start = ByteIndex::from(source.read_u32()?);
58 let end = ByteIndex::from(source.read_u32()?);
59 Ok(Self::new(uri, start, end))
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
65#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
66#[cfg_attr(
67 all(feature = "arbitrary", test),
68 miden_test_serde_macros::serde_test(binary_serde(true))
69)]
70pub struct FileLineCol {
71 pub uri: Uri,
73 pub line: LineNumber,
75 pub column: ColumnNumber,
77}
78
79impl FileLineCol {
80 pub fn new(
82 uri: impl Into<Uri>,
83 line: impl Into<LineNumber>,
84 column: impl Into<ColumnNumber>,
85 ) -> Self {
86 Self {
87 uri: uri.into(),
88 line: line.into(),
89 column: column.into(),
90 }
91 }
92
93 pub fn uri(&self) -> &Uri {
95 &self.uri
96 }
97
98 pub const fn line(&self) -> LineNumber {
100 self.line
101 }
102
103 pub fn move_column(&mut self, offset: i32) {
105 self.column += offset;
106 }
107}
108
109impl fmt::Display for FileLineCol {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(f, "[{}@{}:{}]", self.uri, self.line, self.column)
112 }
113}
114
115impl Serializable for FileLineCol {
116 fn write_into<W: ByteWriter>(&self, target: &mut W) {
117 self.uri.write_into(target);
118 self.line.write_into(target);
119 self.column.write_into(target);
120 }
121}
122
123impl Deserializable for FileLineCol {
124 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
125 let uri = Uri::read_from(source)?;
126 let line = LineNumber::read_from(source)?;
127 let column = ColumnNumber::read_from(source)?;
128 Ok(Self::new(uri, line, column))
129 }
130}
131
132#[cfg(feature = "arbitrary")]
133impl Arbitrary for Location {
134 type Parameters = ();
135 type Strategy = BoxedStrategy<Self>;
136
137 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
138 (any::<Uri>(), any::<u32>(), any::<u32>())
139 .prop_map(|(uri, start, end)| {
140 let (start, end) = if start <= end { (start, end) } else { (end, start) };
141 Self::new(uri, ByteIndex::new(start), ByteIndex::new(end))
142 })
143 .boxed()
144 }
145}
146
147#[cfg(feature = "arbitrary")]
148impl Arbitrary for FileLineCol {
149 type Parameters = ();
150 type Strategy = BoxedStrategy<Self>;
151
152 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
153 (any::<Uri>(), any::<LineNumber>(), any::<ColumnNumber>())
154 .prop_map(|(uri, line, column)| Self::new(uri, line, column))
155 .boxed()
156 }
157}