shape/location.rs
1use std::fmt::Debug;
2use std::hash::Hash;
3use std::ops::Range;
4use std::sync::Arc;
5
6/// Some identifier of the source text that a [`Location`] refers to.
7/// The content only matters to the caller, who will need to be able to use this to give
8/// diagnostics to users.
9///
10/// This might be a file name, reference to an editor panel, or a unique identifier for a
11/// sub-slice of a larger text. It could also be the string content itself.
12///
13/// Consumers that need to distinguish several kinds of source text should
14/// agree on a convention for the identifier string. For example, the
15/// `apollo-shape` crate identifies GraphQL source files by path with a
16/// `graphql:` prefix.
17///
18/// This enum is `#[non_exhaustive]`: variants may be added in a future release
19/// without a breaking change, so downstream `match`es need a wildcard arm.
20#[derive(Clone, Debug, Hash, PartialEq, Eq)]
21#[non_exhaustive]
22pub enum SourceId {
23 /// An arbitrary source identifier from a consumer.
24 Other(Arc<str>),
25}
26
27impl SourceId {
28 pub fn new(id: impl Into<Arc<str>>) -> Self {
29 Self::Other(id.into())
30 }
31
32 /// Create a new [`Location`] within this source text.
33 #[must_use]
34 pub fn location(&self, span: Range<usize>) -> Location {
35 Location {
36 source_id: self.clone(),
37 span,
38 }
39 }
40}
41
42/// The location of a [`crate::Shape`] within the source text that produced it.
43#[derive(Clone, Debug, Hash, PartialEq, Eq)]
44pub struct Location {
45 /// Some identifier correlating `span` to a string the caller controls
46 pub source_id: SourceId,
47 /// The character offset within the source text. 0-indexed, end is exclusive.
48 pub span: Range<usize>,
49}