use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Eq, PartialEq, Hash, Clone, Copy, Ord, PartialOrd)]
pub struct Location {
pub line: u64,
pub column: u64,
}
impl fmt::Debug for Location {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Location({},{})", self.line, self.column)
}
}
impl From<sqlparser::tokenizer::Location> for Location {
fn from(value: sqlparser::tokenizer::Location) -> Self {
Self {
line: value.line,
column: value.column,
}
}
}
#[derive(Eq, PartialEq, Hash, Clone, PartialOrd, Ord, Copy)]
pub struct Span {
pub start: Location,
pub end: Location,
}
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Span({:?}..{:?})", self.start, self.end)
}
}
impl Span {
pub fn new(start: Location, end: Location) -> Self {
Self { start, end }
}
pub fn try_from_sqlparser_span(span: sqlparser::tokenizer::Span) -> Option<Span> {
if span == sqlparser::tokenizer::Span::empty() {
None
} else {
Some(Span {
start: span.start.into(),
end: span.end.into(),
})
}
}
pub fn union(&self, other: &Span) -> Span {
Span {
start: cmp::min(self.start, other.start),
end: cmp::max(self.end, other.end),
}
}
pub fn union_opt(&self, other: &Option<Span>) -> Span {
match other {
Some(other) => self.union(other),
None => *self,
}
}
pub fn union_iter<I: IntoIterator<Item = Span>>(iter: I) -> Option<Span> {
iter.into_iter().reduce(|acc, item| acc.union(&item))
}
}
#[derive(Debug, Clone)]
pub struct Spans(pub Vec<Span>);
impl Spans {
pub fn new() -> Self {
Spans(Vec::new())
}
pub fn first(&self) -> Option<Span> {
self.0.first().copied()
}
pub fn get_spans(&self) -> &[Span] {
&self.0
}
pub fn add_span(&mut self, span: Span) {
self.0.push(span);
}
pub fn iter(&self) -> impl Iterator<Item = &Span> {
self.0.iter()
}
}
impl Default for Spans {
fn default() -> Self {
Self::new()
}
}
impl PartialEq for Spans {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl Eq for Spans {}
impl PartialOrd for Spans {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Spans {
fn cmp(&self, _other: &Self) -> Ordering {
Ordering::Equal
}
}
impl Hash for Spans {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}