Skip to main content

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}