shape/location.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
use apollo_compiler::parser::FileId;
use std::fmt::Display;
use std::ops::Range;
use std::sync::Arc;
/// Some identifier of the source text that a [`Location`] refers to.
/// The content only matters to the caller, who will need to be able to use this to give
/// diagnostics to users.
///
/// This might be a file name, reference to an editor panel, or a unique identifier for a
/// sub-slice of a larger text. It could also be the string content itself.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum SourceId {
/// A key into [`apollo_compiler::Schema`] sources.
GraphQL(FileId),
/// An arbitrary source identifier from a consumer.
Other(Arc<str>),
}
impl SourceId {
pub fn new(id: impl Into<Arc<str>>) -> Self {
Self::Other(id.into())
}
/// Create a new [`Location`] within this source text.
#[must_use]
pub fn location(&self, span: Range<usize>) -> Location {
Location {
source_id: self.clone(),
span,
}
}
}
/// The location of a [`crate::Shape`] within the source text that produced it.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Location {
/// Some identifier correlating `span` to a string the caller controls
pub source_id: SourceId,
/// The character offset within the source text. 0-indexed, end is exclusive.
pub span: Range<usize>,
}
/// Used to track the location of a thing.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Located<T> {
pub value: T,
pub locations: Vec<Location>,
}
impl<T> Located<T> {
pub fn new(value: T, locations: impl IntoIterator<Item = Location>) -> Self {
Self {
value,
locations: locations.into_iter().collect(),
}
}
}
impl<T: Display> Display for Located<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}