nushell/src/parser/parse/span.rs

175 lines
3.8 KiB
Rust
Raw Normal View History

2019-06-22 22:46:16 +02:00
use crate::Text;
2019-06-11 07:53:04 +02:00
use derive_new::new;
2019-06-22 03:36:57 +02:00
use getset::Getters;
use serde::Serialize;
2019-07-09 06:31:26 +02:00
use serde_derive::Deserialize;
2019-06-11 07:53:04 +02:00
2019-07-13 04:07:06 +02:00
#[derive(
new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters,
)]
2019-06-22 03:36:57 +02:00
#[get = "crate"]
2019-06-11 07:53:04 +02:00
pub struct Spanned<T> {
2019-06-27 06:56:48 +02:00
pub span: Span,
pub item: T,
2019-06-11 07:53:04 +02:00
}
2019-07-09 06:31:26 +02:00
impl<T> Spanned<T> {
pub fn spanned(self, span: impl Into<Span>) -> Spanned<T> {
Spanned::from_item(self.item, span.into())
}
}
pub trait SpannedItem: Sized {
fn spanned(self, span: impl Into<Span>) -> Spanned<Self> {
Spanned::from_item(self, span.into())
}
2019-07-08 18:44:53 +02:00
// For now, this is a temporary facility. In many cases, there are other useful spans that we
// could be using, such as the original source spans of JSON or Toml files, but we don't yet
// have the infrastructure to make that work.
fn spanned_unknown(self) -> Spanned<Self> {
Spanned::from_item(self, (0, 0))
}
}
impl<T> SpannedItem for T {}
2019-06-11 07:53:04 +02:00
impl<T> std::ops::Deref for Spanned<T> {
type Target = T;
fn deref(&self) -> &T {
&self.item
}
}
impl<T> Spanned<T> {
crate fn from_item(item: T, span: impl Into<Span>) -> Spanned<T> {
Spanned {
span: span.into(),
item,
}
}
2019-07-18 03:32:19 +02:00
pub fn map<U>(self, input: impl FnOnce(T) -> U) -> Spanned<U> {
2019-06-11 07:53:04 +02:00
let Spanned { span, item } = self;
let mapped = input(item);
Spanned { span, item: mapped }
}
2019-06-22 03:36:57 +02:00
crate fn copy_span<U>(&self, output: U) -> Spanned<U> {
2019-06-22 16:08:53 +02:00
let Spanned { span, .. } = self;
2019-06-22 03:36:57 +02:00
Spanned {
span: *span,
item: output,
}
}
2019-06-22 22:46:16 +02:00
pub fn source(&self, source: &Text) -> Text {
Text::from(self.span().slice(source))
2019-06-22 03:36:57 +02:00
}
2019-06-11 07:53:04 +02:00
}
2019-06-24 02:55:31 +02:00
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
2019-06-11 07:53:04 +02:00
pub struct Span {
crate start: usize,
crate end: usize,
// source: &'source str,
}
2019-07-08 18:44:53 +02:00
impl From<Option<Span>> for Span {
fn from(input: Option<Span>) -> Span {
match input {
None => Span { start: 0, end: 0 },
Some(span) => span,
}
}
}
impl<T> From<&Spanned<T>> for Span {
fn from(input: &Spanned<T>) -> Span {
input.span
}
}
2019-06-22 03:36:57 +02:00
impl From<&Span> for Span {
fn from(input: &Span) -> Span {
*input
}
}
2019-07-16 21:10:25 +02:00
impl From<nom5_locate::LocatedSpan<&str>> for Span {
fn from(input: nom5_locate::LocatedSpan<&str>) -> Span {
2019-06-22 03:36:57 +02:00
Span {
start: input.offset,
end: input.offset + input.fragment.len(),
}
}
}
2019-07-16 21:10:25 +02:00
impl<T> From<(nom5_locate::LocatedSpan<T>, nom5_locate::LocatedSpan<T>)> for Span {
fn from(input: (nom5_locate::LocatedSpan<T>, nom5_locate::LocatedSpan<T>)) -> Span {
2019-06-11 07:53:04 +02:00
Span {
start: input.0.offset,
end: input.1.offset,
}
}
}
impl From<(usize, usize)> for Span {
fn from(input: (usize, usize)) -> Span {
Span {
start: input.0,
end: input.1,
}
}
}
impl From<&std::ops::Range<usize>> for Span {
fn from(input: &std::ops::Range<usize>) -> Span {
Span {
start: input.start,
end: input.end,
}
}
}
impl Span {
2019-07-08 18:44:53 +02:00
pub fn unknown() -> Span {
Span { start: 0, end: 0 }
}
pub fn is_unknown(&self) -> bool {
self.start == 0 && self.end == 0
}
2019-06-22 22:46:16 +02:00
pub fn slice(&self, source: &'a str) -> &'a str {
2019-06-22 03:36:57 +02:00
&source[self.start..self.end]
2019-06-11 07:53:04 +02:00
}
}
impl language_reporting::ReportingSpan for Span {
fn with_start(&self, start: usize) -> Self {
Span {
start,
end: self.end,
}
}
fn with_end(&self, end: usize) -> Self {
Span {
start: self.start,
end,
}
}
fn start(&self) -> usize {
self.start
}
fn end(&self) -> usize {
self.end
}
}