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(
20 all(feature = "arbitrary", test),
21 miden_test_serialization_macros::serialization_test
22)]
23pub struct Location {
24 pub uri: Uri,
26 pub start: ByteIndex,
28 pub end: ByteIndex,
30}
31
32impl Location {
33 pub const fn new(uri: Uri, start: ByteIndex, end: ByteIndex) -> Self {
35 Self { uri, start, end }
36 }
37
38 pub fn uri(&self) -> &Uri {
40 &self.uri
41 }
42
43 pub const fn range(&self) -> Range<ByteIndex> {
45 self.start..self.end
46 }
47}
48
49impl Serializable for Location {
50 fn write_into<W: ByteWriter>(&self, target: &mut W) {
51 self.uri.write_into(target);
52 self.start.to_u32().write_into(target);
53 self.end.to_u32().write_into(target);
54 }
55}
56
57impl Deserializable for Location {
58 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
59 let uri = Uri::read_from(source)?;
60 let start = ByteIndex::from(source.read_u32()?);
61 let end = ByteIndex::from(source.read_u32()?);
62 Ok(Self::new(uri, start, end))
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
68#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
69#[cfg_attr(
70 all(feature = "arbitrary", test),
71 miden_test_serialization_macros::serialization_test
72)]
73pub struct FileLineCol {
74 pub uri: Uri,
76 pub line: LineNumber,
78 pub column: ColumnNumber,
80}
81
82impl FileLineCol {
83 pub fn new(
85 uri: impl Into<Uri>,
86 line: impl Into<LineNumber>,
87 column: impl Into<ColumnNumber>,
88 ) -> Self {
89 Self {
90 uri: uri.into(),
91 line: line.into(),
92 column: column.into(),
93 }
94 }
95
96 pub fn uri(&self) -> &Uri {
98 &self.uri
99 }
100
101 pub const fn line(&self) -> LineNumber {
103 self.line
104 }
105
106 pub fn move_column(&mut self, offset: i32) {
108 self.column += offset;
109 }
110}
111
112impl fmt::Display for FileLineCol {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 write!(f, "[{}@{}:{}]", self.uri, self.line, self.column)
115 }
116}
117
118impl Serializable for FileLineCol {
119 fn write_into<W: ByteWriter>(&self, target: &mut W) {
120 self.uri.write_into(target);
121 self.line.write_into(target);
122 self.column.write_into(target);
123 }
124}
125
126impl Deserializable for FileLineCol {
127 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
128 let uri = Uri::read_from(source)?;
129 let line = LineNumber::read_from(source)?;
130 let column = ColumnNumber::read_from(source)?;
131 Ok(Self::new(uri, line, column))
132 }
133}
134
135#[cfg(feature = "arbitrary")]
136impl Arbitrary for Location {
137 type Parameters = ();
138 type Strategy = BoxedStrategy<Self>;
139
140 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
141 (any::<Uri>(), any::<u32>(), any::<u32>())
142 .prop_map(|(uri, start, end)| {
143 let (start, end) = if start <= end { (start, end) } else { (end, start) };
144 Self::new(uri, ByteIndex::new(start), ByteIndex::new(end))
145 })
146 .boxed()
147 }
148}
149
150#[cfg(feature = "arbitrary")]
151impl Arbitrary for FileLineCol {
152 type Parameters = ();
153 type Strategy = BoxedStrategy<Self>;
154
155 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
156 (any::<Uri>(), any::<LineNumber>(), any::<ColumnNumber>())
157 .prop_map(|(uri, line, column)| Self::new(uri, line, column))
158 .boxed()
159 }
160}