use crate::syntax::{SyntaxKind, SyntaxNode, SyntaxToken};
use super::expressions::Expression;
use super::support::{AstChildren, child, child_token, children};
use super::traits::AstNode;
#[derive(Clone, Debug)]
pub struct ProjectionBody(SyntaxNode);
impl AstNode for ProjectionBody {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::PROJECTION_BODY
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(ProjectionBody(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl ProjectionBody {
pub fn distinct_token(&self) -> Option<SyntaxToken> {
child_token(&self.0, SyntaxKind::KW_DISTINCT)
}
pub fn star_token(&self) -> Option<SyntaxToken> {
self.0
.children()
.find(|n| n.kind() == SyntaxKind::PROJECTION_ITEMS)
.and_then(|n| child_token(&n, SyntaxKind::STAR))
}
pub fn items(&self) -> impl Iterator<Item = ProjectionItem> {
self.0
.children()
.find(|n| n.kind() == SyntaxKind::PROJECTION_ITEMS)
.into_iter()
.flat_map(|n| n.children())
.filter_map(ProjectionItem::cast)
}
pub fn order_by(&self) -> Option<OrderBy> {
child(&self.0)
}
pub fn skip(&self) -> Option<SkipClause> {
child(&self.0)
}
pub fn limit(&self) -> Option<LimitClause> {
child(&self.0)
}
}
#[derive(Clone, Debug)]
pub struct ProjectionItems(SyntaxNode);
impl AstNode for ProjectionItems {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::PROJECTION_ITEMS
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(ProjectionItems(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl ProjectionItems {
pub fn items(&self) -> impl Iterator<Item = ProjectionItem> {
self.0.children().filter_map(ProjectionItem::cast)
}
}
#[derive(Clone, Debug)]
pub struct ProjectionItem(SyntaxNode);
impl AstNode for ProjectionItem {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::PROJECTION_ITEM
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(ProjectionItem(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl ProjectionItem {
pub fn expr(&self) -> Option<Expression> {
let mut last: Option<Expression> = None;
for child in self.0.children_with_tokens() {
if let Some(tok) = child.as_token() {
if tok.kind() == SyntaxKind::KW_AS {
break;
}
continue;
}
if let Some(node) = child.as_node()
&& let Some(e) = Expression::cast(node.clone())
{
last = Some(e);
}
}
last
}
pub fn as_name(&self) -> Option<super::expressions::Variable> {
let mut found_as = false;
for child in self.0.children_with_tokens() {
if let Some(token) = child.as_token() {
if token.kind() == SyntaxKind::KW_AS {
found_as = true;
}
} else if found_as
&& let Some(node) = child.as_node()
&& let Some(v) = super::expressions::Variable::cast(node.clone())
{
return Some(v);
}
}
None
}
}
#[derive(Clone, Debug)]
pub struct OrderBy(SyntaxNode);
impl AstNode for OrderBy {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::ORDER_BY
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(OrderBy(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl OrderBy {
pub fn items(&self) -> AstChildren<SortItem> {
children(&self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SortDirection {
Ascending,
Descending,
}
#[derive(Clone, Debug)]
pub struct SortItem(SyntaxNode);
impl AstNode for SortItem {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::SORT_ITEM
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(SortItem(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl SortItem {
pub fn expr(&self) -> Option<Expression> {
self.0.children().filter_map(Expression::cast).last()
}
pub fn direction(&self) -> Option<SortDirection> {
if child_token(&self.0, SyntaxKind::KW_ASC).is_some()
|| child_token(&self.0, SyntaxKind::KW_ASCENDING).is_some()
{
Some(SortDirection::Ascending)
} else if child_token(&self.0, SyntaxKind::KW_DESC).is_some()
|| child_token(&self.0, SyntaxKind::KW_DESCENDING).is_some()
{
Some(SortDirection::Descending)
} else {
None
}
}
}
#[derive(Clone, Debug)]
pub struct SkipClause(SyntaxNode);
impl AstNode for SkipClause {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::SKIP_CLAUSE
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(SkipClause(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl SkipClause {
pub fn expr(&self) -> Option<Expression> {
child(&self.0)
}
}
#[derive(Clone, Debug)]
pub struct LimitClause(SyntaxNode);
impl AstNode for LimitClause {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::LIMIT_CLAUSE
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(LimitClause(syntax))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
impl LimitClause {
pub fn expr(&self) -> Option<Expression> {
child(&self.0)
}
}