// File automatically generated by ast/asdl_rs.py.

use crate::text_size::TextRange;
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum Ast<R = TextRange> {
    #[is(name = "module")]
    Mod(Mod<R>),
    Stmt(Stmt<R>),
    Expr(Expr<R>),
    ExprContext(ExprContext),
    BoolOp(BoolOp),
    Operator(Operator),
    UnaryOp(UnaryOp),
    CmpOp(CmpOp),
    Comprehension(Comprehension<R>),
    ExceptHandler(ExceptHandler<R>),
    Arguments(Arguments<R>),
    Arg(Arg<R>),
    Keyword(Keyword<R>),
    Alias(Alias<R>),
    WithItem(WithItem<R>),
    MatchCase(MatchCase<R>),
    Pattern(Pattern<R>),
    TypeIgnore(TypeIgnore<R>),
    TypeParam(TypeParam<R>),
}
impl<R> Node for Ast<R> {
    const NAME: &'static str = "AST";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

impl<R> From<Mod<R>> for Ast<R> {
    fn from(node: Mod<R>) -> Self {
        Ast::Mod(node)
    }
}

impl<R> From<Stmt<R>> for Ast<R> {
    fn from(node: Stmt<R>) -> Self {
        Ast::Stmt(node)
    }
}

impl<R> From<Expr<R>> for Ast<R> {
    fn from(node: Expr<R>) -> Self {
        Ast::Expr(node)
    }
}

impl<R> From<ExprContext> for Ast<R> {
    fn from(node: ExprContext) -> Self {
        Ast::ExprContext(node)
    }
}

impl<R> From<BoolOp> for Ast<R> {
    fn from(node: BoolOp) -> Self {
        Ast::BoolOp(node)
    }
}

impl<R> From<Operator> for Ast<R> {
    fn from(node: Operator) -> Self {
        Ast::Operator(node)
    }
}

impl<R> From<UnaryOp> for Ast<R> {
    fn from(node: UnaryOp) -> Self {
        Ast::UnaryOp(node)
    }
}

impl<R> From<CmpOp> for Ast<R> {
    fn from(node: CmpOp) -> Self {
        Ast::CmpOp(node)
    }
}

impl<R> From<Comprehension<R>> for Ast<R> {
    fn from(node: Comprehension<R>) -> Self {
        Ast::Comprehension(node)
    }
}

impl<R> From<ExceptHandler<R>> for Ast<R> {
    fn from(node: ExceptHandler<R>) -> Self {
        Ast::ExceptHandler(node)
    }
}

impl<R> From<Arguments<R>> for Ast<R> {
    fn from(node: Arguments<R>) -> Self {
        Ast::Arguments(node)
    }
}

impl<R> From<Arg<R>> for Ast<R> {
    fn from(node: Arg<R>) -> Self {
        Ast::Arg(node)
    }
}

impl<R> From<Keyword<R>> for Ast<R> {
    fn from(node: Keyword<R>) -> Self {
        Ast::Keyword(node)
    }
}

impl<R> From<Alias<R>> for Ast<R> {
    fn from(node: Alias<R>) -> Self {
        Ast::Alias(node)
    }
}

impl<R> From<WithItem<R>> for Ast<R> {
    fn from(node: WithItem<R>) -> Self {
        Ast::WithItem(node)
    }
}

impl<R> From<MatchCase<R>> for Ast<R> {
    fn from(node: MatchCase<R>) -> Self {
        Ast::MatchCase(node)
    }
}

impl<R> From<Pattern<R>> for Ast<R> {
    fn from(node: Pattern<R>) -> Self {
        Ast::Pattern(node)
    }
}

impl<R> From<TypeIgnore<R>> for Ast<R> {
    fn from(node: TypeIgnore<R>) -> Self {
        Ast::TypeIgnore(node)
    }
}

impl<R> From<TypeParam<R>> for Ast<R> {
    fn from(node: TypeParam<R>) -> Self {
        Ast::TypeParam(node)
    }
}

/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum Mod<R = TextRange> {
    Module(ModModule<R>),
    Interactive(ModInteractive<R>),
    Expression(ModExpression<R>),
    FunctionType(ModFunctionType<R>),
}

/// See also [Module](https://docs.python.org/3/library/ast.html#ast.Module)
#[derive(Clone, Debug, PartialEq)]
pub struct ModModule<R = TextRange> {
    pub range: OptionalRange<R>,
    pub body: Vec<Stmt<R>>,
    pub type_ignores: Vec<TypeIgnore<R>>,
}

impl<R> Node for ModModule<R> {
    const NAME: &'static str = "Module";
    const FIELD_NAMES: &'static [&'static str] = &["body", "type_ignores"];
}
impl<R> From<ModModule<R>> for Mod<R> {
    fn from(payload: ModModule<R>) -> Self {
        Mod::Module(payload)
    }
}
impl<R> From<ModModule<R>> for Ast<R> {
    fn from(payload: ModModule<R>) -> Self {
        Mod::from(payload).into()
    }
}

/// See also [Interactive](https://docs.python.org/3/library/ast.html#ast.Interactive)
#[derive(Clone, Debug, PartialEq)]
pub struct ModInteractive<R = TextRange> {
    pub range: OptionalRange<R>,
    pub body: Vec<Stmt<R>>,
}

impl<R> Node for ModInteractive<R> {
    const NAME: &'static str = "Interactive";
    const FIELD_NAMES: &'static [&'static str] = &["body"];
}
impl<R> From<ModInteractive<R>> for Mod<R> {
    fn from(payload: ModInteractive<R>) -> Self {
        Mod::Interactive(payload)
    }
}
impl<R> From<ModInteractive<R>> for Ast<R> {
    fn from(payload: ModInteractive<R>) -> Self {
        Mod::from(payload).into()
    }
}

/// See also [Expression](https://docs.python.org/3/library/ast.html#ast.Expression)
#[derive(Clone, Debug, PartialEq)]
pub struct ModExpression<R = TextRange> {
    pub range: OptionalRange<R>,
    pub body: Box<Expr<R>>,
}

impl<R> Node for ModExpression<R> {
    const NAME: &'static str = "Expression";
    const FIELD_NAMES: &'static [&'static str] = &["body"];
}
impl<R> From<ModExpression<R>> for Mod<R> {
    fn from(payload: ModExpression<R>) -> Self {
        Mod::Expression(payload)
    }
}
impl<R> From<ModExpression<R>> for Ast<R> {
    fn from(payload: ModExpression<R>) -> Self {
        Mod::from(payload).into()
    }
}

/// See also [FunctionType](https://docs.python.org/3/library/ast.html#ast.FunctionType)
#[derive(Clone, Debug, PartialEq)]
pub struct ModFunctionType<R = TextRange> {
    pub range: OptionalRange<R>,
    pub argtypes: Vec<Expr<R>>,
    pub returns: Box<Expr<R>>,
}

impl<R> Node for ModFunctionType<R> {
    const NAME: &'static str = "FunctionType";
    const FIELD_NAMES: &'static [&'static str] = &["argtypes", "returns"];
}
impl<R> From<ModFunctionType<R>> for Mod<R> {
    fn from(payload: ModFunctionType<R>) -> Self {
        Mod::FunctionType(payload)
    }
}
impl<R> From<ModFunctionType<R>> for Ast<R> {
    fn from(payload: ModFunctionType<R>) -> Self {
        Mod::from(payload).into()
    }
}

impl<R> Node for Mod<R> {
    const NAME: &'static str = "mod";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [stmt](https://docs.python.org/3/library/ast.html#ast.stmt)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum Stmt<R = TextRange> {
    #[is(name = "function_def_stmt")]
    FunctionDef(StmtFunctionDef<R>),
    #[is(name = "async_function_def_stmt")]
    AsyncFunctionDef(StmtAsyncFunctionDef<R>),
    #[is(name = "class_def_stmt")]
    ClassDef(StmtClassDef<R>),
    #[is(name = "return_stmt")]
    Return(StmtReturn<R>),
    #[is(name = "delete_stmt")]
    Delete(StmtDelete<R>),
    #[is(name = "assign_stmt")]
    Assign(StmtAssign<R>),
    #[is(name = "type_alias_stmt")]
    TypeAlias(StmtTypeAlias<R>),
    #[is(name = "aug_assign_stmt")]
    AugAssign(StmtAugAssign<R>),
    #[is(name = "ann_assign_stmt")]
    AnnAssign(StmtAnnAssign<R>),
    #[is(name = "for_stmt")]
    For(StmtFor<R>),
    #[is(name = "async_for_stmt")]
    AsyncFor(StmtAsyncFor<R>),
    #[is(name = "while_stmt")]
    While(StmtWhile<R>),
    #[is(name = "if_stmt")]
    If(StmtIf<R>),
    #[is(name = "with_stmt")]
    With(StmtWith<R>),
    #[is(name = "async_with_stmt")]
    AsyncWith(StmtAsyncWith<R>),
    #[is(name = "match_stmt")]
    Match(StmtMatch<R>),
    #[is(name = "raise_stmt")]
    Raise(StmtRaise<R>),
    #[is(name = "try_stmt")]
    Try(StmtTry<R>),
    #[is(name = "try_star_stmt")]
    TryStar(StmtTryStar<R>),
    #[is(name = "assert_stmt")]
    Assert(StmtAssert<R>),
    #[is(name = "import_stmt")]
    Import(StmtImport<R>),
    #[is(name = "import_from_stmt")]
    ImportFrom(StmtImportFrom<R>),
    #[is(name = "global_stmt")]
    Global(StmtGlobal<R>),
    #[is(name = "nonlocal_stmt")]
    Nonlocal(StmtNonlocal<R>),
    #[is(name = "expr_stmt")]
    Expr(StmtExpr<R>),
    #[is(name = "pass_stmt")]
    Pass(StmtPass<R>),
    #[is(name = "break_stmt")]
    Break(StmtBreak<R>),
    #[is(name = "continue_stmt")]
    Continue(StmtContinue<R>),
}

/// See also [FunctionDef](https://docs.python.org/3/library/ast.html#ast.FunctionDef)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtFunctionDef<R = TextRange> {
    pub range: R,
    pub name: Identifier,
    pub args: Box<Arguments<R>>,
    pub body: Vec<Stmt<R>>,
    pub decorator_list: Vec<Expr<R>>,
    pub returns: Option<Box<Expr<R>>>,
    pub type_comment: Option<String>,
    pub type_params: Vec<TypeParam<R>>,
}

impl<R> Node for StmtFunctionDef<R> {
    const NAME: &'static str = "FunctionDef";
    const FIELD_NAMES: &'static [&'static str] = &[
        "name",
        "args",
        "body",
        "decorator_list",
        "returns",
        "type_comment",
        "type_params",
    ];
}
impl<R> From<StmtFunctionDef<R>> for Stmt<R> {
    fn from(payload: StmtFunctionDef<R>) -> Self {
        Stmt::FunctionDef(payload)
    }
}
impl<R> From<StmtFunctionDef<R>> for Ast<R> {
    fn from(payload: StmtFunctionDef<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [AsyncFunctionDef](https://docs.python.org/3/library/ast.html#ast.AsyncFunctionDef)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAsyncFunctionDef<R = TextRange> {
    pub range: R,
    pub name: Identifier,
    pub args: Box<Arguments<R>>,
    pub body: Vec<Stmt<R>>,
    pub decorator_list: Vec<Expr<R>>,
    pub returns: Option<Box<Expr<R>>>,
    pub type_comment: Option<String>,
    pub type_params: Vec<TypeParam<R>>,
}

impl<R> Node for StmtAsyncFunctionDef<R> {
    const NAME: &'static str = "AsyncFunctionDef";
    const FIELD_NAMES: &'static [&'static str] = &[
        "name",
        "args",
        "body",
        "decorator_list",
        "returns",
        "type_comment",
        "type_params",
    ];
}
impl<R> From<StmtAsyncFunctionDef<R>> for Stmt<R> {
    fn from(payload: StmtAsyncFunctionDef<R>) -> Self {
        Stmt::AsyncFunctionDef(payload)
    }
}
impl<R> From<StmtAsyncFunctionDef<R>> for Ast<R> {
    fn from(payload: StmtAsyncFunctionDef<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [ClassDef](https://docs.python.org/3/library/ast.html#ast.ClassDef)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtClassDef<R = TextRange> {
    pub range: R,
    pub name: Identifier,
    pub bases: Vec<Expr<R>>,
    pub keywords: Vec<Keyword<R>>,
    pub body: Vec<Stmt<R>>,
    pub decorator_list: Vec<Expr<R>>,
    pub type_params: Vec<TypeParam<R>>,
}

impl<R> Node for StmtClassDef<R> {
    const NAME: &'static str = "ClassDef";
    const FIELD_NAMES: &'static [&'static str] = &[
        "name",
        "bases",
        "keywords",
        "body",
        "decorator_list",
        "type_params",
    ];
}
impl<R> From<StmtClassDef<R>> for Stmt<R> {
    fn from(payload: StmtClassDef<R>) -> Self {
        Stmt::ClassDef(payload)
    }
}
impl<R> From<StmtClassDef<R>> for Ast<R> {
    fn from(payload: StmtClassDef<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Return](https://docs.python.org/3/library/ast.html#ast.Return)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtReturn<R = TextRange> {
    pub range: R,
    pub value: Option<Box<Expr<R>>>,
}

impl<R> Node for StmtReturn<R> {
    const NAME: &'static str = "Return";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<StmtReturn<R>> for Stmt<R> {
    fn from(payload: StmtReturn<R>) -> Self {
        Stmt::Return(payload)
    }
}
impl<R> From<StmtReturn<R>> for Ast<R> {
    fn from(payload: StmtReturn<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Delete](https://docs.python.org/3/library/ast.html#ast.Delete)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtDelete<R = TextRange> {
    pub range: R,
    pub targets: Vec<Expr<R>>,
}

impl<R> Node for StmtDelete<R> {
    const NAME: &'static str = "Delete";
    const FIELD_NAMES: &'static [&'static str] = &["targets"];
}
impl<R> From<StmtDelete<R>> for Stmt<R> {
    fn from(payload: StmtDelete<R>) -> Self {
        Stmt::Delete(payload)
    }
}
impl<R> From<StmtDelete<R>> for Ast<R> {
    fn from(payload: StmtDelete<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Assign](https://docs.python.org/3/library/ast.html#ast.Assign)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAssign<R = TextRange> {
    pub range: R,
    pub targets: Vec<Expr<R>>,
    pub value: Box<Expr<R>>,
    pub type_comment: Option<String>,
}

impl<R> Node for StmtAssign<R> {
    const NAME: &'static str = "Assign";
    const FIELD_NAMES: &'static [&'static str] = &["targets", "value", "type_comment"];
}
impl<R> From<StmtAssign<R>> for Stmt<R> {
    fn from(payload: StmtAssign<R>) -> Self {
        Stmt::Assign(payload)
    }
}
impl<R> From<StmtAssign<R>> for Ast<R> {
    fn from(payload: StmtAssign<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [TypeAlias](https://docs.python.org/3/library/ast.html#ast.TypeAlias)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtTypeAlias<R = TextRange> {
    pub range: R,
    pub name: Box<Expr<R>>,
    pub type_params: Vec<TypeParam<R>>,
    pub value: Box<Expr<R>>,
}

impl<R> Node for StmtTypeAlias<R> {
    const NAME: &'static str = "TypeAlias";
    const FIELD_NAMES: &'static [&'static str] = &["name", "type_params", "value"];
}
impl<R> From<StmtTypeAlias<R>> for Stmt<R> {
    fn from(payload: StmtTypeAlias<R>) -> Self {
        Stmt::TypeAlias(payload)
    }
}
impl<R> From<StmtTypeAlias<R>> for Ast<R> {
    fn from(payload: StmtTypeAlias<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [AugAssign](https://docs.python.org/3/library/ast.html#ast.AugAssign)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAugAssign<R = TextRange> {
    pub range: R,
    pub target: Box<Expr<R>>,
    pub op: Operator,
    pub value: Box<Expr<R>>,
}

impl<R> Node for StmtAugAssign<R> {
    const NAME: &'static str = "AugAssign";
    const FIELD_NAMES: &'static [&'static str] = &["target", "op", "value"];
}
impl<R> From<StmtAugAssign<R>> for Stmt<R> {
    fn from(payload: StmtAugAssign<R>) -> Self {
        Stmt::AugAssign(payload)
    }
}
impl<R> From<StmtAugAssign<R>> for Ast<R> {
    fn from(payload: StmtAugAssign<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [AnnAssign](https://docs.python.org/3/library/ast.html#ast.AnnAssign)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAnnAssign<R = TextRange> {
    pub range: R,
    pub target: Box<Expr<R>>,
    pub annotation: Box<Expr<R>>,
    pub value: Option<Box<Expr<R>>>,
    pub simple: bool,
}

impl<R> Node for StmtAnnAssign<R> {
    const NAME: &'static str = "AnnAssign";
    const FIELD_NAMES: &'static [&'static str] = &["target", "annotation", "value", "simple"];
}
impl<R> From<StmtAnnAssign<R>> for Stmt<R> {
    fn from(payload: StmtAnnAssign<R>) -> Self {
        Stmt::AnnAssign(payload)
    }
}
impl<R> From<StmtAnnAssign<R>> for Ast<R> {
    fn from(payload: StmtAnnAssign<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [For](https://docs.python.org/3/library/ast.html#ast.For)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtFor<R = TextRange> {
    pub range: R,
    pub target: Box<Expr<R>>,
    pub iter: Box<Expr<R>>,
    pub body: Vec<Stmt<R>>,
    pub orelse: Vec<Stmt<R>>,
    pub type_comment: Option<String>,
}

impl<R> Node for StmtFor<R> {
    const NAME: &'static str = "For";
    const FIELD_NAMES: &'static [&'static str] =
        &["target", "iter", "body", "orelse", "type_comment"];
}
impl<R> From<StmtFor<R>> for Stmt<R> {
    fn from(payload: StmtFor<R>) -> Self {
        Stmt::For(payload)
    }
}
impl<R> From<StmtFor<R>> for Ast<R> {
    fn from(payload: StmtFor<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [AsyncFor](https://docs.python.org/3/library/ast.html#ast.AsyncFor)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAsyncFor<R = TextRange> {
    pub range: R,
    pub target: Box<Expr<R>>,
    pub iter: Box<Expr<R>>,
    pub body: Vec<Stmt<R>>,
    pub orelse: Vec<Stmt<R>>,
    pub type_comment: Option<String>,
}

impl<R> Node for StmtAsyncFor<R> {
    const NAME: &'static str = "AsyncFor";
    const FIELD_NAMES: &'static [&'static str] =
        &["target", "iter", "body", "orelse", "type_comment"];
}
impl<R> From<StmtAsyncFor<R>> for Stmt<R> {
    fn from(payload: StmtAsyncFor<R>) -> Self {
        Stmt::AsyncFor(payload)
    }
}
impl<R> From<StmtAsyncFor<R>> for Ast<R> {
    fn from(payload: StmtAsyncFor<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [While](https://docs.python.org/3/library/ast.html#ast.While)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtWhile<R = TextRange> {
    pub range: R,
    pub test: Box<Expr<R>>,
    pub body: Vec<Stmt<R>>,
    pub orelse: Vec<Stmt<R>>,
}

impl<R> Node for StmtWhile<R> {
    const NAME: &'static str = "While";
    const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"];
}
impl<R> From<StmtWhile<R>> for Stmt<R> {
    fn from(payload: StmtWhile<R>) -> Self {
        Stmt::While(payload)
    }
}
impl<R> From<StmtWhile<R>> for Ast<R> {
    fn from(payload: StmtWhile<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [If](https://docs.python.org/3/library/ast.html#ast.If)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtIf<R = TextRange> {
    pub range: R,
    pub test: Box<Expr<R>>,
    pub body: Vec<Stmt<R>>,
    pub orelse: Vec<Stmt<R>>,
}

impl<R> Node for StmtIf<R> {
    const NAME: &'static str = "If";
    const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"];
}
impl<R> From<StmtIf<R>> for Stmt<R> {
    fn from(payload: StmtIf<R>) -> Self {
        Stmt::If(payload)
    }
}
impl<R> From<StmtIf<R>> for Ast<R> {
    fn from(payload: StmtIf<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [With](https://docs.python.org/3/library/ast.html#ast.With)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtWith<R = TextRange> {
    pub range: R,
    pub items: Vec<WithItem<R>>,
    pub body: Vec<Stmt<R>>,
    pub type_comment: Option<String>,
}

impl<R> Node for StmtWith<R> {
    const NAME: &'static str = "With";
    const FIELD_NAMES: &'static [&'static str] = &["items", "body", "type_comment"];
}
impl<R> From<StmtWith<R>> for Stmt<R> {
    fn from(payload: StmtWith<R>) -> Self {
        Stmt::With(payload)
    }
}
impl<R> From<StmtWith<R>> for Ast<R> {
    fn from(payload: StmtWith<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [AsyncWith](https://docs.python.org/3/library/ast.html#ast.AsyncWith)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAsyncWith<R = TextRange> {
    pub range: R,
    pub items: Vec<WithItem<R>>,
    pub body: Vec<Stmt<R>>,
    pub type_comment: Option<String>,
}

impl<R> Node for StmtAsyncWith<R> {
    const NAME: &'static str = "AsyncWith";
    const FIELD_NAMES: &'static [&'static str] = &["items", "body", "type_comment"];
}
impl<R> From<StmtAsyncWith<R>> for Stmt<R> {
    fn from(payload: StmtAsyncWith<R>) -> Self {
        Stmt::AsyncWith(payload)
    }
}
impl<R> From<StmtAsyncWith<R>> for Ast<R> {
    fn from(payload: StmtAsyncWith<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Match](https://docs.python.org/3/library/ast.html#ast.Match)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtMatch<R = TextRange> {
    pub range: R,
    pub subject: Box<Expr<R>>,
    pub cases: Vec<MatchCase<R>>,
}

impl<R> Node for StmtMatch<R> {
    const NAME: &'static str = "Match";
    const FIELD_NAMES: &'static [&'static str] = &["subject", "cases"];
}
impl<R> From<StmtMatch<R>> for Stmt<R> {
    fn from(payload: StmtMatch<R>) -> Self {
        Stmt::Match(payload)
    }
}
impl<R> From<StmtMatch<R>> for Ast<R> {
    fn from(payload: StmtMatch<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Raise](https://docs.python.org/3/library/ast.html#ast.Raise)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtRaise<R = TextRange> {
    pub range: R,
    pub exc: Option<Box<Expr<R>>>,
    pub cause: Option<Box<Expr<R>>>,
}

impl<R> Node for StmtRaise<R> {
    const NAME: &'static str = "Raise";
    const FIELD_NAMES: &'static [&'static str] = &["exc", "cause"];
}
impl<R> From<StmtRaise<R>> for Stmt<R> {
    fn from(payload: StmtRaise<R>) -> Self {
        Stmt::Raise(payload)
    }
}
impl<R> From<StmtRaise<R>> for Ast<R> {
    fn from(payload: StmtRaise<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Try](https://docs.python.org/3/library/ast.html#ast.Try)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtTry<R = TextRange> {
    pub range: R,
    pub body: Vec<Stmt<R>>,
    pub handlers: Vec<ExceptHandler<R>>,
    pub orelse: Vec<Stmt<R>>,
    pub finalbody: Vec<Stmt<R>>,
}

impl<R> Node for StmtTry<R> {
    const NAME: &'static str = "Try";
    const FIELD_NAMES: &'static [&'static str] = &["body", "handlers", "orelse", "finalbody"];
}
impl<R> From<StmtTry<R>> for Stmt<R> {
    fn from(payload: StmtTry<R>) -> Self {
        Stmt::Try(payload)
    }
}
impl<R> From<StmtTry<R>> for Ast<R> {
    fn from(payload: StmtTry<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [TryStar](https://docs.python.org/3/library/ast.html#ast.TryStar)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtTryStar<R = TextRange> {
    pub range: R,
    pub body: Vec<Stmt<R>>,
    pub handlers: Vec<ExceptHandler<R>>,
    pub orelse: Vec<Stmt<R>>,
    pub finalbody: Vec<Stmt<R>>,
}

impl<R> Node for StmtTryStar<R> {
    const NAME: &'static str = "TryStar";
    const FIELD_NAMES: &'static [&'static str] = &["body", "handlers", "orelse", "finalbody"];
}
impl<R> From<StmtTryStar<R>> for Stmt<R> {
    fn from(payload: StmtTryStar<R>) -> Self {
        Stmt::TryStar(payload)
    }
}
impl<R> From<StmtTryStar<R>> for Ast<R> {
    fn from(payload: StmtTryStar<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Assert](https://docs.python.org/3/library/ast.html#ast.Assert)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAssert<R = TextRange> {
    pub range: R,
    pub test: Box<Expr<R>>,
    pub msg: Option<Box<Expr<R>>>,
}

impl<R> Node for StmtAssert<R> {
    const NAME: &'static str = "Assert";
    const FIELD_NAMES: &'static [&'static str] = &["test", "msg"];
}
impl<R> From<StmtAssert<R>> for Stmt<R> {
    fn from(payload: StmtAssert<R>) -> Self {
        Stmt::Assert(payload)
    }
}
impl<R> From<StmtAssert<R>> for Ast<R> {
    fn from(payload: StmtAssert<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Import](https://docs.python.org/3/library/ast.html#ast.Import)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtImport<R = TextRange> {
    pub range: R,
    pub names: Vec<Alias<R>>,
}

impl<R> Node for StmtImport<R> {
    const NAME: &'static str = "Import";
    const FIELD_NAMES: &'static [&'static str] = &["names"];
}
impl<R> From<StmtImport<R>> for Stmt<R> {
    fn from(payload: StmtImport<R>) -> Self {
        Stmt::Import(payload)
    }
}
impl<R> From<StmtImport<R>> for Ast<R> {
    fn from(payload: StmtImport<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [ImportFrom](https://docs.python.org/3/library/ast.html#ast.ImportFrom)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtImportFrom<R = TextRange> {
    pub range: R,
    pub module: Option<Identifier>,
    pub names: Vec<Alias<R>>,
    pub level: Option<Int>,
}

impl<R> Node for StmtImportFrom<R> {
    const NAME: &'static str = "ImportFrom";
    const FIELD_NAMES: &'static [&'static str] = &["module", "names", "level"];
}
impl<R> From<StmtImportFrom<R>> for Stmt<R> {
    fn from(payload: StmtImportFrom<R>) -> Self {
        Stmt::ImportFrom(payload)
    }
}
impl<R> From<StmtImportFrom<R>> for Ast<R> {
    fn from(payload: StmtImportFrom<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Global](https://docs.python.org/3/library/ast.html#ast.Global)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtGlobal<R = TextRange> {
    pub range: R,
    pub names: Vec<Identifier>,
}

impl<R> Node for StmtGlobal<R> {
    const NAME: &'static str = "Global";
    const FIELD_NAMES: &'static [&'static str] = &["names"];
}
impl<R> From<StmtGlobal<R>> for Stmt<R> {
    fn from(payload: StmtGlobal<R>) -> Self {
        Stmt::Global(payload)
    }
}
impl<R> From<StmtGlobal<R>> for Ast<R> {
    fn from(payload: StmtGlobal<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Nonlocal](https://docs.python.org/3/library/ast.html#ast.Nonlocal)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtNonlocal<R = TextRange> {
    pub range: R,
    pub names: Vec<Identifier>,
}

impl<R> Node for StmtNonlocal<R> {
    const NAME: &'static str = "Nonlocal";
    const FIELD_NAMES: &'static [&'static str] = &["names"];
}
impl<R> From<StmtNonlocal<R>> for Stmt<R> {
    fn from(payload: StmtNonlocal<R>) -> Self {
        Stmt::Nonlocal(payload)
    }
}
impl<R> From<StmtNonlocal<R>> for Ast<R> {
    fn from(payload: StmtNonlocal<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Expr](https://docs.python.org/3/library/ast.html#ast.Expr)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtExpr<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
}

impl<R> Node for StmtExpr<R> {
    const NAME: &'static str = "Expr";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<StmtExpr<R>> for Stmt<R> {
    fn from(payload: StmtExpr<R>) -> Self {
        Stmt::Expr(payload)
    }
}
impl<R> From<StmtExpr<R>> for Ast<R> {
    fn from(payload: StmtExpr<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Pass](https://docs.python.org/3/library/ast.html#ast.Pass)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtPass<R = TextRange> {
    pub range: R,
}

impl<R> Node for StmtPass<R> {
    const NAME: &'static str = "Pass";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl<R> From<StmtPass<R>> for Stmt<R> {
    fn from(payload: StmtPass<R>) -> Self {
        Stmt::Pass(payload)
    }
}
impl<R> From<StmtPass<R>> for Ast<R> {
    fn from(payload: StmtPass<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Break](https://docs.python.org/3/library/ast.html#ast.Break)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtBreak<R = TextRange> {
    pub range: R,
}

impl<R> Node for StmtBreak<R> {
    const NAME: &'static str = "Break";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl<R> From<StmtBreak<R>> for Stmt<R> {
    fn from(payload: StmtBreak<R>) -> Self {
        Stmt::Break(payload)
    }
}
impl<R> From<StmtBreak<R>> for Ast<R> {
    fn from(payload: StmtBreak<R>) -> Self {
        Stmt::from(payload).into()
    }
}

/// See also [Continue](https://docs.python.org/3/library/ast.html#ast.Continue)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtContinue<R = TextRange> {
    pub range: R,
}

impl<R> Node for StmtContinue<R> {
    const NAME: &'static str = "Continue";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl<R> From<StmtContinue<R>> for Stmt<R> {
    fn from(payload: StmtContinue<R>) -> Self {
        Stmt::Continue(payload)
    }
}
impl<R> From<StmtContinue<R>> for Ast<R> {
    fn from(payload: StmtContinue<R>) -> Self {
        Stmt::from(payload).into()
    }
}

impl<R> Node for Stmt<R> {
    const NAME: &'static str = "stmt";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [expr](https://docs.python.org/3/library/ast.html#ast.expr)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum Expr<R = TextRange> {
    #[is(name = "bool_op_expr")]
    BoolOp(ExprBoolOp<R>),
    #[is(name = "named_expr_expr")]
    NamedExpr(ExprNamedExpr<R>),
    #[is(name = "bin_op_expr")]
    BinOp(ExprBinOp<R>),
    #[is(name = "unary_op_expr")]
    UnaryOp(ExprUnaryOp<R>),
    #[is(name = "lambda_expr")]
    Lambda(ExprLambda<R>),
    #[is(name = "if_exp_expr")]
    IfExp(ExprIfExp<R>),
    #[is(name = "dict_expr")]
    Dict(ExprDict<R>),
    #[is(name = "set_expr")]
    Set(ExprSet<R>),
    #[is(name = "list_comp_expr")]
    ListComp(ExprListComp<R>),
    #[is(name = "set_comp_expr")]
    SetComp(ExprSetComp<R>),
    #[is(name = "dict_comp_expr")]
    DictComp(ExprDictComp<R>),
    #[is(name = "generator_exp_expr")]
    GeneratorExp(ExprGeneratorExp<R>),
    #[is(name = "await_expr")]
    Await(ExprAwait<R>),
    #[is(name = "yield_expr")]
    Yield(ExprYield<R>),
    #[is(name = "yield_from_expr")]
    YieldFrom(ExprYieldFrom<R>),
    #[is(name = "compare_expr")]
    Compare(ExprCompare<R>),
    #[is(name = "call_expr")]
    Call(ExprCall<R>),
    #[is(name = "formatted_value_expr")]
    FormattedValue(ExprFormattedValue<R>),
    #[is(name = "joined_str_expr")]
    JoinedStr(ExprJoinedStr<R>),
    #[is(name = "constant_expr")]
    Constant(ExprConstant<R>),
    #[is(name = "attribute_expr")]
    Attribute(ExprAttribute<R>),
    #[is(name = "subscript_expr")]
    Subscript(ExprSubscript<R>),
    #[is(name = "starred_expr")]
    Starred(ExprStarred<R>),
    #[is(name = "name_expr")]
    Name(ExprName<R>),
    #[is(name = "list_expr")]
    List(ExprList<R>),
    #[is(name = "tuple_expr")]
    Tuple(ExprTuple<R>),
    #[is(name = "slice_expr")]
    Slice(ExprSlice<R>),
}

/// See also [BoolOp](https://docs.python.org/3/library/ast.html#ast.BoolOp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprBoolOp<R = TextRange> {
    pub range: R,
    pub op: BoolOp,
    pub values: Vec<Expr<R>>,
}

impl<R> Node for ExprBoolOp<R> {
    const NAME: &'static str = "BoolOp";
    const FIELD_NAMES: &'static [&'static str] = &["op", "values"];
}
impl<R> From<ExprBoolOp<R>> for Expr<R> {
    fn from(payload: ExprBoolOp<R>) -> Self {
        Expr::BoolOp(payload)
    }
}
impl<R> From<ExprBoolOp<R>> for Ast<R> {
    fn from(payload: ExprBoolOp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [NamedExpr](https://docs.python.org/3/library/ast.html#ast.NamedExpr)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprNamedExpr<R = TextRange> {
    pub range: R,
    pub target: Box<Expr<R>>,
    pub value: Box<Expr<R>>,
}

impl<R> Node for ExprNamedExpr<R> {
    const NAME: &'static str = "NamedExpr";
    const FIELD_NAMES: &'static [&'static str] = &["target", "value"];
}
impl<R> From<ExprNamedExpr<R>> for Expr<R> {
    fn from(payload: ExprNamedExpr<R>) -> Self {
        Expr::NamedExpr(payload)
    }
}
impl<R> From<ExprNamedExpr<R>> for Ast<R> {
    fn from(payload: ExprNamedExpr<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [BinOp](https://docs.python.org/3/library/ast.html#ast.BinOp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprBinOp<R = TextRange> {
    pub range: R,
    pub left: Box<Expr<R>>,
    pub op: Operator,
    pub right: Box<Expr<R>>,
}

impl<R> Node for ExprBinOp<R> {
    const NAME: &'static str = "BinOp";
    const FIELD_NAMES: &'static [&'static str] = &["left", "op", "right"];
}
impl<R> From<ExprBinOp<R>> for Expr<R> {
    fn from(payload: ExprBinOp<R>) -> Self {
        Expr::BinOp(payload)
    }
}
impl<R> From<ExprBinOp<R>> for Ast<R> {
    fn from(payload: ExprBinOp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [UnaryOp](https://docs.python.org/3/library/ast.html#ast.UnaryOp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprUnaryOp<R = TextRange> {
    pub range: R,
    pub op: UnaryOp,
    pub operand: Box<Expr<R>>,
}

impl<R> Node for ExprUnaryOp<R> {
    const NAME: &'static str = "UnaryOp";
    const FIELD_NAMES: &'static [&'static str] = &["op", "operand"];
}
impl<R> From<ExprUnaryOp<R>> for Expr<R> {
    fn from(payload: ExprUnaryOp<R>) -> Self {
        Expr::UnaryOp(payload)
    }
}
impl<R> From<ExprUnaryOp<R>> for Ast<R> {
    fn from(payload: ExprUnaryOp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Lambda](https://docs.python.org/3/library/ast.html#ast.Lambda)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprLambda<R = TextRange> {
    pub range: R,
    pub args: Box<Arguments<R>>,
    pub body: Box<Expr<R>>,
}

impl<R> Node for ExprLambda<R> {
    const NAME: &'static str = "Lambda";
    const FIELD_NAMES: &'static [&'static str] = &["args", "body"];
}
impl<R> From<ExprLambda<R>> for Expr<R> {
    fn from(payload: ExprLambda<R>) -> Self {
        Expr::Lambda(payload)
    }
}
impl<R> From<ExprLambda<R>> for Ast<R> {
    fn from(payload: ExprLambda<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [IfExp](https://docs.python.org/3/library/ast.html#ast.IfExp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprIfExp<R = TextRange> {
    pub range: R,
    pub test: Box<Expr<R>>,
    pub body: Box<Expr<R>>,
    pub orelse: Box<Expr<R>>,
}

impl<R> Node for ExprIfExp<R> {
    const NAME: &'static str = "IfExp";
    const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"];
}
impl<R> From<ExprIfExp<R>> for Expr<R> {
    fn from(payload: ExprIfExp<R>) -> Self {
        Expr::IfExp(payload)
    }
}
impl<R> From<ExprIfExp<R>> for Ast<R> {
    fn from(payload: ExprIfExp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Dict](https://docs.python.org/3/library/ast.html#ast.Dict)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprDict<R = TextRange> {
    pub range: R,
    pub keys: Vec<Option<Expr<R>>>,
    pub values: Vec<Expr<R>>,
}

impl<R> Node for ExprDict<R> {
    const NAME: &'static str = "Dict";
    const FIELD_NAMES: &'static [&'static str] = &["keys", "values"];
}
impl<R> From<ExprDict<R>> for Expr<R> {
    fn from(payload: ExprDict<R>) -> Self {
        Expr::Dict(payload)
    }
}
impl<R> From<ExprDict<R>> for Ast<R> {
    fn from(payload: ExprDict<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Set](https://docs.python.org/3/library/ast.html#ast.Set)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprSet<R = TextRange> {
    pub range: R,
    pub elts: Vec<Expr<R>>,
}

impl<R> Node for ExprSet<R> {
    const NAME: &'static str = "Set";
    const FIELD_NAMES: &'static [&'static str] = &["elts"];
}
impl<R> From<ExprSet<R>> for Expr<R> {
    fn from(payload: ExprSet<R>) -> Self {
        Expr::Set(payload)
    }
}
impl<R> From<ExprSet<R>> for Ast<R> {
    fn from(payload: ExprSet<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [ListComp](https://docs.python.org/3/library/ast.html#ast.ListComp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprListComp<R = TextRange> {
    pub range: R,
    pub elt: Box<Expr<R>>,
    pub generators: Vec<Comprehension<R>>,
}

impl<R> Node for ExprListComp<R> {
    const NAME: &'static str = "ListComp";
    const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"];
}
impl<R> From<ExprListComp<R>> for Expr<R> {
    fn from(payload: ExprListComp<R>) -> Self {
        Expr::ListComp(payload)
    }
}
impl<R> From<ExprListComp<R>> for Ast<R> {
    fn from(payload: ExprListComp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [SetComp](https://docs.python.org/3/library/ast.html#ast.SetComp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprSetComp<R = TextRange> {
    pub range: R,
    pub elt: Box<Expr<R>>,
    pub generators: Vec<Comprehension<R>>,
}

impl<R> Node for ExprSetComp<R> {
    const NAME: &'static str = "SetComp";
    const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"];
}
impl<R> From<ExprSetComp<R>> for Expr<R> {
    fn from(payload: ExprSetComp<R>) -> Self {
        Expr::SetComp(payload)
    }
}
impl<R> From<ExprSetComp<R>> for Ast<R> {
    fn from(payload: ExprSetComp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [DictComp](https://docs.python.org/3/library/ast.html#ast.DictComp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprDictComp<R = TextRange> {
    pub range: R,
    pub key: Box<Expr<R>>,
    pub value: Box<Expr<R>>,
    pub generators: Vec<Comprehension<R>>,
}

impl<R> Node for ExprDictComp<R> {
    const NAME: &'static str = "DictComp";
    const FIELD_NAMES: &'static [&'static str] = &["key", "value", "generators"];
}
impl<R> From<ExprDictComp<R>> for Expr<R> {
    fn from(payload: ExprDictComp<R>) -> Self {
        Expr::DictComp(payload)
    }
}
impl<R> From<ExprDictComp<R>> for Ast<R> {
    fn from(payload: ExprDictComp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [GeneratorExp](https://docs.python.org/3/library/ast.html#ast.GeneratorExp)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprGeneratorExp<R = TextRange> {
    pub range: R,
    pub elt: Box<Expr<R>>,
    pub generators: Vec<Comprehension<R>>,
}

impl<R> Node for ExprGeneratorExp<R> {
    const NAME: &'static str = "GeneratorExp";
    const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"];
}
impl<R> From<ExprGeneratorExp<R>> for Expr<R> {
    fn from(payload: ExprGeneratorExp<R>) -> Self {
        Expr::GeneratorExp(payload)
    }
}
impl<R> From<ExprGeneratorExp<R>> for Ast<R> {
    fn from(payload: ExprGeneratorExp<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Await](https://docs.python.org/3/library/ast.html#ast.Await)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprAwait<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
}

impl<R> Node for ExprAwait<R> {
    const NAME: &'static str = "Await";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<ExprAwait<R>> for Expr<R> {
    fn from(payload: ExprAwait<R>) -> Self {
        Expr::Await(payload)
    }
}
impl<R> From<ExprAwait<R>> for Ast<R> {
    fn from(payload: ExprAwait<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Yield](https://docs.python.org/3/library/ast.html#ast.Yield)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprYield<R = TextRange> {
    pub range: R,
    pub value: Option<Box<Expr<R>>>,
}

impl<R> Node for ExprYield<R> {
    const NAME: &'static str = "Yield";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<ExprYield<R>> for Expr<R> {
    fn from(payload: ExprYield<R>) -> Self {
        Expr::Yield(payload)
    }
}
impl<R> From<ExprYield<R>> for Ast<R> {
    fn from(payload: ExprYield<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [YieldFrom](https://docs.python.org/3/library/ast.html#ast.YieldFrom)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprYieldFrom<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
}

impl<R> Node for ExprYieldFrom<R> {
    const NAME: &'static str = "YieldFrom";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<ExprYieldFrom<R>> for Expr<R> {
    fn from(payload: ExprYieldFrom<R>) -> Self {
        Expr::YieldFrom(payload)
    }
}
impl<R> From<ExprYieldFrom<R>> for Ast<R> {
    fn from(payload: ExprYieldFrom<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Compare](https://docs.python.org/3/library/ast.html#ast.Compare)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprCompare<R = TextRange> {
    pub range: R,
    pub left: Box<Expr<R>>,
    pub ops: Vec<CmpOp>,
    pub comparators: Vec<Expr<R>>,
}

impl<R> Node for ExprCompare<R> {
    const NAME: &'static str = "Compare";
    const FIELD_NAMES: &'static [&'static str] = &["left", "ops", "comparators"];
}
impl<R> From<ExprCompare<R>> for Expr<R> {
    fn from(payload: ExprCompare<R>) -> Self {
        Expr::Compare(payload)
    }
}
impl<R> From<ExprCompare<R>> for Ast<R> {
    fn from(payload: ExprCompare<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Call](https://docs.python.org/3/library/ast.html#ast.Call)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprCall<R = TextRange> {
    pub range: R,
    pub func: Box<Expr<R>>,
    pub args: Vec<Expr<R>>,
    pub keywords: Vec<Keyword<R>>,
}

impl<R> Node for ExprCall<R> {
    const NAME: &'static str = "Call";
    const FIELD_NAMES: &'static [&'static str] = &["func", "args", "keywords"];
}
impl<R> From<ExprCall<R>> for Expr<R> {
    fn from(payload: ExprCall<R>) -> Self {
        Expr::Call(payload)
    }
}
impl<R> From<ExprCall<R>> for Ast<R> {
    fn from(payload: ExprCall<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [FormattedValue](https://docs.python.org/3/library/ast.html#ast.FormattedValue)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprFormattedValue<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
    pub conversion: ConversionFlag,
    pub format_spec: Option<Box<Expr<R>>>,
}

impl<R> Node for ExprFormattedValue<R> {
    const NAME: &'static str = "FormattedValue";
    const FIELD_NAMES: &'static [&'static str] = &["value", "conversion", "format_spec"];
}
impl<R> From<ExprFormattedValue<R>> for Expr<R> {
    fn from(payload: ExprFormattedValue<R>) -> Self {
        Expr::FormattedValue(payload)
    }
}
impl<R> From<ExprFormattedValue<R>> for Ast<R> {
    fn from(payload: ExprFormattedValue<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [JoinedStr](https://docs.python.org/3/library/ast.html#ast.JoinedStr)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprJoinedStr<R = TextRange> {
    pub range: R,
    pub values: Vec<Expr<R>>,
}

impl<R> Node for ExprJoinedStr<R> {
    const NAME: &'static str = "JoinedStr";
    const FIELD_NAMES: &'static [&'static str] = &["values"];
}
impl<R> From<ExprJoinedStr<R>> for Expr<R> {
    fn from(payload: ExprJoinedStr<R>) -> Self {
        Expr::JoinedStr(payload)
    }
}
impl<R> From<ExprJoinedStr<R>> for Ast<R> {
    fn from(payload: ExprJoinedStr<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Constant](https://docs.python.org/3/library/ast.html#ast.Constant)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprConstant<R = TextRange> {
    pub range: R,
    pub value: Constant,
    pub kind: Option<String>,
}

impl<R> Node for ExprConstant<R> {
    const NAME: &'static str = "Constant";
    const FIELD_NAMES: &'static [&'static str] = &["value", "kind"];
}
impl<R> From<ExprConstant<R>> for Expr<R> {
    fn from(payload: ExprConstant<R>) -> Self {
        Expr::Constant(payload)
    }
}
impl<R> From<ExprConstant<R>> for Ast<R> {
    fn from(payload: ExprConstant<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Attribute](https://docs.python.org/3/library/ast.html#ast.Attribute)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprAttribute<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
    pub attr: Identifier,
    pub ctx: ExprContext,
}

impl<R> Node for ExprAttribute<R> {
    const NAME: &'static str = "Attribute";
    const FIELD_NAMES: &'static [&'static str] = &["value", "attr", "ctx"];
}
impl<R> From<ExprAttribute<R>> for Expr<R> {
    fn from(payload: ExprAttribute<R>) -> Self {
        Expr::Attribute(payload)
    }
}
impl<R> From<ExprAttribute<R>> for Ast<R> {
    fn from(payload: ExprAttribute<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Subscript](https://docs.python.org/3/library/ast.html#ast.Subscript)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprSubscript<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
    pub slice: Box<Expr<R>>,
    pub ctx: ExprContext,
}

impl<R> Node for ExprSubscript<R> {
    const NAME: &'static str = "Subscript";
    const FIELD_NAMES: &'static [&'static str] = &["value", "slice", "ctx"];
}
impl<R> From<ExprSubscript<R>> for Expr<R> {
    fn from(payload: ExprSubscript<R>) -> Self {
        Expr::Subscript(payload)
    }
}
impl<R> From<ExprSubscript<R>> for Ast<R> {
    fn from(payload: ExprSubscript<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Starred](https://docs.python.org/3/library/ast.html#ast.Starred)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprStarred<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
    pub ctx: ExprContext,
}

impl<R> Node for ExprStarred<R> {
    const NAME: &'static str = "Starred";
    const FIELD_NAMES: &'static [&'static str] = &["value", "ctx"];
}
impl<R> From<ExprStarred<R>> for Expr<R> {
    fn from(payload: ExprStarred<R>) -> Self {
        Expr::Starred(payload)
    }
}
impl<R> From<ExprStarred<R>> for Ast<R> {
    fn from(payload: ExprStarred<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Name](https://docs.python.org/3/library/ast.html#ast.Name)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprName<R = TextRange> {
    pub range: R,
    pub id: Identifier,
    pub ctx: ExprContext,
}

impl<R> Node for ExprName<R> {
    const NAME: &'static str = "Name";
    const FIELD_NAMES: &'static [&'static str] = &["id", "ctx"];
}
impl<R> From<ExprName<R>> for Expr<R> {
    fn from(payload: ExprName<R>) -> Self {
        Expr::Name(payload)
    }
}
impl<R> From<ExprName<R>> for Ast<R> {
    fn from(payload: ExprName<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [List](https://docs.python.org/3/library/ast.html#ast.List)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprList<R = TextRange> {
    pub range: R,
    pub elts: Vec<Expr<R>>,
    pub ctx: ExprContext,
}

impl<R> Node for ExprList<R> {
    const NAME: &'static str = "List";
    const FIELD_NAMES: &'static [&'static str] = &["elts", "ctx"];
}
impl<R> From<ExprList<R>> for Expr<R> {
    fn from(payload: ExprList<R>) -> Self {
        Expr::List(payload)
    }
}
impl<R> From<ExprList<R>> for Ast<R> {
    fn from(payload: ExprList<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Tuple](https://docs.python.org/3/library/ast.html#ast.Tuple)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprTuple<R = TextRange> {
    pub range: R,
    pub elts: Vec<Expr<R>>,
    pub ctx: ExprContext,
}

impl<R> Node for ExprTuple<R> {
    const NAME: &'static str = "Tuple";
    const FIELD_NAMES: &'static [&'static str] = &["elts", "ctx"];
}
impl<R> From<ExprTuple<R>> for Expr<R> {
    fn from(payload: ExprTuple<R>) -> Self {
        Expr::Tuple(payload)
    }
}
impl<R> From<ExprTuple<R>> for Ast<R> {
    fn from(payload: ExprTuple<R>) -> Self {
        Expr::from(payload).into()
    }
}

/// See also [Slice](https://docs.python.org/3/library/ast.html#ast.Slice)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprSlice<R = TextRange> {
    pub range: R,
    pub lower: Option<Box<Expr<R>>>,
    pub upper: Option<Box<Expr<R>>>,
    pub step: Option<Box<Expr<R>>>,
}

impl<R> Node for ExprSlice<R> {
    const NAME: &'static str = "Slice";
    const FIELD_NAMES: &'static [&'static str] = &["lower", "upper", "step"];
}
impl<R> From<ExprSlice<R>> for Expr<R> {
    fn from(payload: ExprSlice<R>) -> Self {
        Expr::Slice(payload)
    }
}
impl<R> From<ExprSlice<R>> for Ast<R> {
    fn from(payload: ExprSlice<R>) -> Self {
        Expr::from(payload).into()
    }
}

impl<R> Node for Expr<R> {
    const NAME: &'static str = "expr";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [expr_context](https://docs.python.org/3/library/ast.html#ast.expr_context)
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
pub enum ExprContext {
    Load,
    Store,
    Del,
}
impl ExprContext {
    #[inline]
    pub const fn load(&self) -> Option<ExprContextLoad> {
        match self {
            ExprContext::Load => Some(ExprContextLoad),
            _ => None,
        }
    }

    #[inline]
    pub const fn store(&self) -> Option<ExprContextStore> {
        match self {
            ExprContext::Store => Some(ExprContextStore),
            _ => None,
        }
    }

    #[inline]
    pub const fn del(&self) -> Option<ExprContextDel> {
        match self {
            ExprContext::Del => Some(ExprContextDel),
            _ => None,
        }
    }
}

pub struct ExprContextLoad;
impl From<ExprContextLoad> for ExprContext {
    fn from(_: ExprContextLoad) -> Self {
        ExprContext::Load
    }
}
impl<R> From<ExprContextLoad> for Ast<R> {
    fn from(_: ExprContextLoad) -> Self {
        ExprContext::Load.into()
    }
}
impl Node for ExprContextLoad {
    const NAME: &'static str = "Load";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<ExprContext> for ExprContextLoad {
    #[inline]
    fn eq(&self, other: &ExprContext) -> bool {
        matches!(other, ExprContext::Load)
    }
}

pub struct ExprContextStore;
impl From<ExprContextStore> for ExprContext {
    fn from(_: ExprContextStore) -> Self {
        ExprContext::Store
    }
}
impl<R> From<ExprContextStore> for Ast<R> {
    fn from(_: ExprContextStore) -> Self {
        ExprContext::Store.into()
    }
}
impl Node for ExprContextStore {
    const NAME: &'static str = "Store";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<ExprContext> for ExprContextStore {
    #[inline]
    fn eq(&self, other: &ExprContext) -> bool {
        matches!(other, ExprContext::Store)
    }
}

pub struct ExprContextDel;
impl From<ExprContextDel> for ExprContext {
    fn from(_: ExprContextDel) -> Self {
        ExprContext::Del
    }
}
impl<R> From<ExprContextDel> for Ast<R> {
    fn from(_: ExprContextDel) -> Self {
        ExprContext::Del.into()
    }
}
impl Node for ExprContextDel {
    const NAME: &'static str = "Del";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<ExprContext> for ExprContextDel {
    #[inline]
    fn eq(&self, other: &ExprContext) -> bool {
        matches!(other, ExprContext::Del)
    }
}

impl Node for ExprContext {
    const NAME: &'static str = "expr_context";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [boolop](https://docs.python.org/3/library/ast.html#ast.boolop)
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
pub enum BoolOp {
    And,
    Or,
}
impl BoolOp {
    #[inline]
    pub const fn and(&self) -> Option<BoolOpAnd> {
        match self {
            BoolOp::And => Some(BoolOpAnd),
            _ => None,
        }
    }

    #[inline]
    pub const fn or(&self) -> Option<BoolOpOr> {
        match self {
            BoolOp::Or => Some(BoolOpOr),
            _ => None,
        }
    }
}

pub struct BoolOpAnd;
impl From<BoolOpAnd> for BoolOp {
    fn from(_: BoolOpAnd) -> Self {
        BoolOp::And
    }
}
impl<R> From<BoolOpAnd> for Ast<R> {
    fn from(_: BoolOpAnd) -> Self {
        BoolOp::And.into()
    }
}
impl Node for BoolOpAnd {
    const NAME: &'static str = "And";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<BoolOp> for BoolOpAnd {
    #[inline]
    fn eq(&self, other: &BoolOp) -> bool {
        matches!(other, BoolOp::And)
    }
}

pub struct BoolOpOr;
impl From<BoolOpOr> for BoolOp {
    fn from(_: BoolOpOr) -> Self {
        BoolOp::Or
    }
}
impl<R> From<BoolOpOr> for Ast<R> {
    fn from(_: BoolOpOr) -> Self {
        BoolOp::Or.into()
    }
}
impl Node for BoolOpOr {
    const NAME: &'static str = "Or";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<BoolOp> for BoolOpOr {
    #[inline]
    fn eq(&self, other: &BoolOp) -> bool {
        matches!(other, BoolOp::Or)
    }
}

impl Node for BoolOp {
    const NAME: &'static str = "boolop";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [operator](https://docs.python.org/3/library/ast.html#ast.operator)
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
pub enum Operator {
    Add,
    Sub,
    Mult,
    MatMult,
    Div,
    Mod,
    Pow,
    LShift,
    RShift,
    BitOr,
    BitXor,
    BitAnd,
    FloorDiv,
}
impl Operator {
    #[inline]
    pub const fn operator_add(&self) -> Option<OperatorAdd> {
        match self {
            Operator::Add => Some(OperatorAdd),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_sub(&self) -> Option<OperatorSub> {
        match self {
            Operator::Sub => Some(OperatorSub),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_mult(&self) -> Option<OperatorMult> {
        match self {
            Operator::Mult => Some(OperatorMult),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_mat_mult(&self) -> Option<OperatorMatMult> {
        match self {
            Operator::MatMult => Some(OperatorMatMult),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_div(&self) -> Option<OperatorDiv> {
        match self {
            Operator::Div => Some(OperatorDiv),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_mod(&self) -> Option<OperatorMod> {
        match self {
            Operator::Mod => Some(OperatorMod),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_pow(&self) -> Option<OperatorPow> {
        match self {
            Operator::Pow => Some(OperatorPow),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_l_shift(&self) -> Option<OperatorLShift> {
        match self {
            Operator::LShift => Some(OperatorLShift),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_r_shift(&self) -> Option<OperatorRShift> {
        match self {
            Operator::RShift => Some(OperatorRShift),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_bit_or(&self) -> Option<OperatorBitOr> {
        match self {
            Operator::BitOr => Some(OperatorBitOr),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_bit_xor(&self) -> Option<OperatorBitXor> {
        match self {
            Operator::BitXor => Some(OperatorBitXor),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_bit_and(&self) -> Option<OperatorBitAnd> {
        match self {
            Operator::BitAnd => Some(OperatorBitAnd),
            _ => None,
        }
    }

    #[inline]
    pub const fn operator_floor_div(&self) -> Option<OperatorFloorDiv> {
        match self {
            Operator::FloorDiv => Some(OperatorFloorDiv),
            _ => None,
        }
    }
}

pub struct OperatorAdd;
impl From<OperatorAdd> for Operator {
    fn from(_: OperatorAdd) -> Self {
        Operator::Add
    }
}
impl<R> From<OperatorAdd> for Ast<R> {
    fn from(_: OperatorAdd) -> Self {
        Operator::Add.into()
    }
}
impl Node for OperatorAdd {
    const NAME: &'static str = "Add";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorAdd {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Add)
    }
}

pub struct OperatorSub;
impl From<OperatorSub> for Operator {
    fn from(_: OperatorSub) -> Self {
        Operator::Sub
    }
}
impl<R> From<OperatorSub> for Ast<R> {
    fn from(_: OperatorSub) -> Self {
        Operator::Sub.into()
    }
}
impl Node for OperatorSub {
    const NAME: &'static str = "Sub";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorSub {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Sub)
    }
}

pub struct OperatorMult;
impl From<OperatorMult> for Operator {
    fn from(_: OperatorMult) -> Self {
        Operator::Mult
    }
}
impl<R> From<OperatorMult> for Ast<R> {
    fn from(_: OperatorMult) -> Self {
        Operator::Mult.into()
    }
}
impl Node for OperatorMult {
    const NAME: &'static str = "Mult";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorMult {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Mult)
    }
}

pub struct OperatorMatMult;
impl From<OperatorMatMult> for Operator {
    fn from(_: OperatorMatMult) -> Self {
        Operator::MatMult
    }
}
impl<R> From<OperatorMatMult> for Ast<R> {
    fn from(_: OperatorMatMult) -> Self {
        Operator::MatMult.into()
    }
}
impl Node for OperatorMatMult {
    const NAME: &'static str = "MatMult";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorMatMult {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::MatMult)
    }
}

pub struct OperatorDiv;
impl From<OperatorDiv> for Operator {
    fn from(_: OperatorDiv) -> Self {
        Operator::Div
    }
}
impl<R> From<OperatorDiv> for Ast<R> {
    fn from(_: OperatorDiv) -> Self {
        Operator::Div.into()
    }
}
impl Node for OperatorDiv {
    const NAME: &'static str = "Div";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorDiv {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Div)
    }
}

pub struct OperatorMod;
impl From<OperatorMod> for Operator {
    fn from(_: OperatorMod) -> Self {
        Operator::Mod
    }
}
impl<R> From<OperatorMod> for Ast<R> {
    fn from(_: OperatorMod) -> Self {
        Operator::Mod.into()
    }
}
impl Node for OperatorMod {
    const NAME: &'static str = "Mod";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorMod {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Mod)
    }
}

pub struct OperatorPow;
impl From<OperatorPow> for Operator {
    fn from(_: OperatorPow) -> Self {
        Operator::Pow
    }
}
impl<R> From<OperatorPow> for Ast<R> {
    fn from(_: OperatorPow) -> Self {
        Operator::Pow.into()
    }
}
impl Node for OperatorPow {
    const NAME: &'static str = "Pow";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorPow {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::Pow)
    }
}

pub struct OperatorLShift;
impl From<OperatorLShift> for Operator {
    fn from(_: OperatorLShift) -> Self {
        Operator::LShift
    }
}
impl<R> From<OperatorLShift> for Ast<R> {
    fn from(_: OperatorLShift) -> Self {
        Operator::LShift.into()
    }
}
impl Node for OperatorLShift {
    const NAME: &'static str = "LShift";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorLShift {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::LShift)
    }
}

pub struct OperatorRShift;
impl From<OperatorRShift> for Operator {
    fn from(_: OperatorRShift) -> Self {
        Operator::RShift
    }
}
impl<R> From<OperatorRShift> for Ast<R> {
    fn from(_: OperatorRShift) -> Self {
        Operator::RShift.into()
    }
}
impl Node for OperatorRShift {
    const NAME: &'static str = "RShift";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorRShift {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::RShift)
    }
}

pub struct OperatorBitOr;
impl From<OperatorBitOr> for Operator {
    fn from(_: OperatorBitOr) -> Self {
        Operator::BitOr
    }
}
impl<R> From<OperatorBitOr> for Ast<R> {
    fn from(_: OperatorBitOr) -> Self {
        Operator::BitOr.into()
    }
}
impl Node for OperatorBitOr {
    const NAME: &'static str = "BitOr";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorBitOr {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::BitOr)
    }
}

pub struct OperatorBitXor;
impl From<OperatorBitXor> for Operator {
    fn from(_: OperatorBitXor) -> Self {
        Operator::BitXor
    }
}
impl<R> From<OperatorBitXor> for Ast<R> {
    fn from(_: OperatorBitXor) -> Self {
        Operator::BitXor.into()
    }
}
impl Node for OperatorBitXor {
    const NAME: &'static str = "BitXor";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorBitXor {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::BitXor)
    }
}

pub struct OperatorBitAnd;
impl From<OperatorBitAnd> for Operator {
    fn from(_: OperatorBitAnd) -> Self {
        Operator::BitAnd
    }
}
impl<R> From<OperatorBitAnd> for Ast<R> {
    fn from(_: OperatorBitAnd) -> Self {
        Operator::BitAnd.into()
    }
}
impl Node for OperatorBitAnd {
    const NAME: &'static str = "BitAnd";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorBitAnd {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::BitAnd)
    }
}

pub struct OperatorFloorDiv;
impl From<OperatorFloorDiv> for Operator {
    fn from(_: OperatorFloorDiv) -> Self {
        Operator::FloorDiv
    }
}
impl<R> From<OperatorFloorDiv> for Ast<R> {
    fn from(_: OperatorFloorDiv) -> Self {
        Operator::FloorDiv.into()
    }
}
impl Node for OperatorFloorDiv {
    const NAME: &'static str = "FloorDiv";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<Operator> for OperatorFloorDiv {
    #[inline]
    fn eq(&self, other: &Operator) -> bool {
        matches!(other, Operator::FloorDiv)
    }
}

impl Node for Operator {
    const NAME: &'static str = "operator";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [unaryop](https://docs.python.org/3/library/ast.html#ast.unaryop)
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
pub enum UnaryOp {
    Invert,
    Not,
    UAdd,
    USub,
}
impl UnaryOp {
    #[inline]
    pub const fn invert(&self) -> Option<UnaryOpInvert> {
        match self {
            UnaryOp::Invert => Some(UnaryOpInvert),
            _ => None,
        }
    }

    #[inline]
    pub const fn not(&self) -> Option<UnaryOpNot> {
        match self {
            UnaryOp::Not => Some(UnaryOpNot),
            _ => None,
        }
    }

    #[inline]
    pub const fn u_add(&self) -> Option<UnaryOpUAdd> {
        match self {
            UnaryOp::UAdd => Some(UnaryOpUAdd),
            _ => None,
        }
    }

    #[inline]
    pub const fn u_sub(&self) -> Option<UnaryOpUSub> {
        match self {
            UnaryOp::USub => Some(UnaryOpUSub),
            _ => None,
        }
    }
}

pub struct UnaryOpInvert;
impl From<UnaryOpInvert> for UnaryOp {
    fn from(_: UnaryOpInvert) -> Self {
        UnaryOp::Invert
    }
}
impl<R> From<UnaryOpInvert> for Ast<R> {
    fn from(_: UnaryOpInvert) -> Self {
        UnaryOp::Invert.into()
    }
}
impl Node for UnaryOpInvert {
    const NAME: &'static str = "Invert";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<UnaryOp> for UnaryOpInvert {
    #[inline]
    fn eq(&self, other: &UnaryOp) -> bool {
        matches!(other, UnaryOp::Invert)
    }
}

pub struct UnaryOpNot;
impl From<UnaryOpNot> for UnaryOp {
    fn from(_: UnaryOpNot) -> Self {
        UnaryOp::Not
    }
}
impl<R> From<UnaryOpNot> for Ast<R> {
    fn from(_: UnaryOpNot) -> Self {
        UnaryOp::Not.into()
    }
}
impl Node for UnaryOpNot {
    const NAME: &'static str = "Not";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<UnaryOp> for UnaryOpNot {
    #[inline]
    fn eq(&self, other: &UnaryOp) -> bool {
        matches!(other, UnaryOp::Not)
    }
}

pub struct UnaryOpUAdd;
impl From<UnaryOpUAdd> for UnaryOp {
    fn from(_: UnaryOpUAdd) -> Self {
        UnaryOp::UAdd
    }
}
impl<R> From<UnaryOpUAdd> for Ast<R> {
    fn from(_: UnaryOpUAdd) -> Self {
        UnaryOp::UAdd.into()
    }
}
impl Node for UnaryOpUAdd {
    const NAME: &'static str = "UAdd";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<UnaryOp> for UnaryOpUAdd {
    #[inline]
    fn eq(&self, other: &UnaryOp) -> bool {
        matches!(other, UnaryOp::UAdd)
    }
}

pub struct UnaryOpUSub;
impl From<UnaryOpUSub> for UnaryOp {
    fn from(_: UnaryOpUSub) -> Self {
        UnaryOp::USub
    }
}
impl<R> From<UnaryOpUSub> for Ast<R> {
    fn from(_: UnaryOpUSub) -> Self {
        UnaryOp::USub.into()
    }
}
impl Node for UnaryOpUSub {
    const NAME: &'static str = "USub";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<UnaryOp> for UnaryOpUSub {
    #[inline]
    fn eq(&self, other: &UnaryOp) -> bool {
        matches!(other, UnaryOp::USub)
    }
}

impl Node for UnaryOp {
    const NAME: &'static str = "unaryop";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [cmpop](https://docs.python.org/3/library/ast.html#ast.cmpop)
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
pub enum CmpOp {
    Eq,
    NotEq,
    Lt,
    LtE,
    Gt,
    GtE,
    Is,
    IsNot,
    In,
    NotIn,
}
impl CmpOp {
    #[inline]
    pub const fn cmp_op_eq(&self) -> Option<CmpOpEq> {
        match self {
            CmpOp::Eq => Some(CmpOpEq),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_not_eq(&self) -> Option<CmpOpNotEq> {
        match self {
            CmpOp::NotEq => Some(CmpOpNotEq),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_lt(&self) -> Option<CmpOpLt> {
        match self {
            CmpOp::Lt => Some(CmpOpLt),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_lt_e(&self) -> Option<CmpOpLtE> {
        match self {
            CmpOp::LtE => Some(CmpOpLtE),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_gt(&self) -> Option<CmpOpGt> {
        match self {
            CmpOp::Gt => Some(CmpOpGt),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_gt_e(&self) -> Option<CmpOpGtE> {
        match self {
            CmpOp::GtE => Some(CmpOpGtE),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_is(&self) -> Option<CmpOpIs> {
        match self {
            CmpOp::Is => Some(CmpOpIs),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_is_not(&self) -> Option<CmpOpIsNot> {
        match self {
            CmpOp::IsNot => Some(CmpOpIsNot),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_in(&self) -> Option<CmpOpIn> {
        match self {
            CmpOp::In => Some(CmpOpIn),
            _ => None,
        }
    }

    #[inline]
    pub const fn cmp_op_not_in(&self) -> Option<CmpOpNotIn> {
        match self {
            CmpOp::NotIn => Some(CmpOpNotIn),
            _ => None,
        }
    }
}

pub struct CmpOpEq;
impl From<CmpOpEq> for CmpOp {
    fn from(_: CmpOpEq) -> Self {
        CmpOp::Eq
    }
}
impl<R> From<CmpOpEq> for Ast<R> {
    fn from(_: CmpOpEq) -> Self {
        CmpOp::Eq.into()
    }
}
impl Node for CmpOpEq {
    const NAME: &'static str = "Eq";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpEq {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::Eq)
    }
}

pub struct CmpOpNotEq;
impl From<CmpOpNotEq> for CmpOp {
    fn from(_: CmpOpNotEq) -> Self {
        CmpOp::NotEq
    }
}
impl<R> From<CmpOpNotEq> for Ast<R> {
    fn from(_: CmpOpNotEq) -> Self {
        CmpOp::NotEq.into()
    }
}
impl Node for CmpOpNotEq {
    const NAME: &'static str = "NotEq";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpNotEq {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::NotEq)
    }
}

pub struct CmpOpLt;
impl From<CmpOpLt> for CmpOp {
    fn from(_: CmpOpLt) -> Self {
        CmpOp::Lt
    }
}
impl<R> From<CmpOpLt> for Ast<R> {
    fn from(_: CmpOpLt) -> Self {
        CmpOp::Lt.into()
    }
}
impl Node for CmpOpLt {
    const NAME: &'static str = "Lt";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpLt {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::Lt)
    }
}

pub struct CmpOpLtE;
impl From<CmpOpLtE> for CmpOp {
    fn from(_: CmpOpLtE) -> Self {
        CmpOp::LtE
    }
}
impl<R> From<CmpOpLtE> for Ast<R> {
    fn from(_: CmpOpLtE) -> Self {
        CmpOp::LtE.into()
    }
}
impl Node for CmpOpLtE {
    const NAME: &'static str = "LtE";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpLtE {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::LtE)
    }
}

pub struct CmpOpGt;
impl From<CmpOpGt> for CmpOp {
    fn from(_: CmpOpGt) -> Self {
        CmpOp::Gt
    }
}
impl<R> From<CmpOpGt> for Ast<R> {
    fn from(_: CmpOpGt) -> Self {
        CmpOp::Gt.into()
    }
}
impl Node for CmpOpGt {
    const NAME: &'static str = "Gt";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpGt {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::Gt)
    }
}

pub struct CmpOpGtE;
impl From<CmpOpGtE> for CmpOp {
    fn from(_: CmpOpGtE) -> Self {
        CmpOp::GtE
    }
}
impl<R> From<CmpOpGtE> for Ast<R> {
    fn from(_: CmpOpGtE) -> Self {
        CmpOp::GtE.into()
    }
}
impl Node for CmpOpGtE {
    const NAME: &'static str = "GtE";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpGtE {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::GtE)
    }
}

pub struct CmpOpIs;
impl From<CmpOpIs> for CmpOp {
    fn from(_: CmpOpIs) -> Self {
        CmpOp::Is
    }
}
impl<R> From<CmpOpIs> for Ast<R> {
    fn from(_: CmpOpIs) -> Self {
        CmpOp::Is.into()
    }
}
impl Node for CmpOpIs {
    const NAME: &'static str = "Is";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpIs {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::Is)
    }
}

pub struct CmpOpIsNot;
impl From<CmpOpIsNot> for CmpOp {
    fn from(_: CmpOpIsNot) -> Self {
        CmpOp::IsNot
    }
}
impl<R> From<CmpOpIsNot> for Ast<R> {
    fn from(_: CmpOpIsNot) -> Self {
        CmpOp::IsNot.into()
    }
}
impl Node for CmpOpIsNot {
    const NAME: &'static str = "IsNot";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpIsNot {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::IsNot)
    }
}

pub struct CmpOpIn;
impl From<CmpOpIn> for CmpOp {
    fn from(_: CmpOpIn) -> Self {
        CmpOp::In
    }
}
impl<R> From<CmpOpIn> for Ast<R> {
    fn from(_: CmpOpIn) -> Self {
        CmpOp::In.into()
    }
}
impl Node for CmpOpIn {
    const NAME: &'static str = "In";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpIn {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::In)
    }
}

pub struct CmpOpNotIn;
impl From<CmpOpNotIn> for CmpOp {
    fn from(_: CmpOpNotIn) -> Self {
        CmpOp::NotIn
    }
}
impl<R> From<CmpOpNotIn> for Ast<R> {
    fn from(_: CmpOpNotIn) -> Self {
        CmpOp::NotIn.into()
    }
}
impl Node for CmpOpNotIn {
    const NAME: &'static str = "NotIn";
    const FIELD_NAMES: &'static [&'static str] = &[];
}
impl std::cmp::PartialEq<CmpOp> for CmpOpNotIn {
    #[inline]
    fn eq(&self, other: &CmpOp) -> bool {
        matches!(other, CmpOp::NotIn)
    }
}

impl Node for CmpOp {
    const NAME: &'static str = "cmpop";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [comprehension](https://docs.python.org/3/library/ast.html#ast.comprehension)
#[derive(Clone, Debug, PartialEq)]
pub struct Comprehension<R = TextRange> {
    pub range: OptionalRange<R>,
    pub target: Expr<R>,
    pub iter: Expr<R>,
    pub ifs: Vec<Expr<R>>,
    pub is_async: bool,
}

impl<R> Node for Comprehension<R> {
    const NAME: &'static str = "comprehension";
    const FIELD_NAMES: &'static [&'static str] = &["target", "iter", "ifs", "is_async"];
}

/// See also [excepthandler](https://docs.python.org/3/library/ast.html#ast.excepthandler)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum ExceptHandler<R = TextRange> {
    ExceptHandler(ExceptHandlerExceptHandler<R>),
}

/// See also [ExceptHandler](https://docs.python.org/3/library/ast.html#ast.ExceptHandler)
#[derive(Clone, Debug, PartialEq)]
pub struct ExceptHandlerExceptHandler<R = TextRange> {
    pub range: R,
    pub type_: Option<Box<Expr<R>>>,
    pub name: Option<Identifier>,
    pub body: Vec<Stmt<R>>,
}

impl<R> Node for ExceptHandlerExceptHandler<R> {
    const NAME: &'static str = "ExceptHandler";
    const FIELD_NAMES: &'static [&'static str] = &["type", "name", "body"];
}
impl<R> From<ExceptHandlerExceptHandler<R>> for ExceptHandler<R> {
    fn from(payload: ExceptHandlerExceptHandler<R>) -> Self {
        ExceptHandler::ExceptHandler(payload)
    }
}
impl<R> From<ExceptHandlerExceptHandler<R>> for Ast<R> {
    fn from(payload: ExceptHandlerExceptHandler<R>) -> Self {
        ExceptHandler::from(payload).into()
    }
}

impl<R> Node for ExceptHandler<R> {
    const NAME: &'static str = "excepthandler";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [arguments](https://docs.python.org/3/library/ast.html#ast.arguments)
#[derive(Clone, Debug, PartialEq)]
pub struct PythonArguments<R = TextRange> {
    pub range: OptionalRange<R>,
    pub posonlyargs: Vec<Arg<R>>,
    pub args: Vec<Arg<R>>,
    pub vararg: Option<Box<Arg<R>>>,
    pub kwonlyargs: Vec<Arg<R>>,
    pub kw_defaults: Vec<Expr<R>>,
    pub kwarg: Option<Box<Arg<R>>>,
    pub defaults: Vec<Expr<R>>,
}

impl<R> Node for PythonArguments<R> {
    const NAME: &'static str = "arguments";
    const FIELD_NAMES: &'static [&'static str] = &[
        "posonlyargs",
        "args",
        "vararg",
        "kwonlyargs",
        "kw_defaults",
        "kwarg",
        "defaults",
    ];
}

/// See also [arg](https://docs.python.org/3/library/ast.html#ast.arg)
#[derive(Clone, Debug, PartialEq)]
pub struct Arg<R = TextRange> {
    pub range: R,
    pub arg: Identifier,
    pub annotation: Option<Box<Expr<R>>>,
    pub type_comment: Option<String>,
}

impl<R> Node for Arg<R> {
    const NAME: &'static str = "arg";
    const FIELD_NAMES: &'static [&'static str] = &["arg", "annotation", "type_comment"];
}

/// See also [keyword](https://docs.python.org/3/library/ast.html#ast.keyword)
#[derive(Clone, Debug, PartialEq)]
pub struct Keyword<R = TextRange> {
    pub range: R,
    pub arg: Option<Identifier>,
    pub value: Expr<R>,
}

impl<R> Node for Keyword<R> {
    const NAME: &'static str = "keyword";
    const FIELD_NAMES: &'static [&'static str] = &["arg", "value"];
}

/// See also [alias](https://docs.python.org/3/library/ast.html#ast.alias)
#[derive(Clone, Debug, PartialEq)]
pub struct Alias<R = TextRange> {
    pub range: R,
    pub name: Identifier,
    pub asname: Option<Identifier>,
}

impl<R> Node for Alias<R> {
    const NAME: &'static str = "alias";
    const FIELD_NAMES: &'static [&'static str] = &["name", "asname"];
}

/// See also [withitem](https://docs.python.org/3/library/ast.html#ast.withitem)
#[derive(Clone, Debug, PartialEq)]
pub struct WithItem<R = TextRange> {
    pub range: OptionalRange<R>,
    pub context_expr: Expr<R>,
    pub optional_vars: Option<Box<Expr<R>>>,
}

impl<R> Node for WithItem<R> {
    const NAME: &'static str = "withitem";
    const FIELD_NAMES: &'static [&'static str] = &["context_expr", "optional_vars"];
}

/// See also [match_case](https://docs.python.org/3/library/ast.html#ast.match_case)
#[derive(Clone, Debug, PartialEq)]
pub struct MatchCase<R = TextRange> {
    pub range: OptionalRange<R>,
    pub pattern: Pattern<R>,
    pub guard: Option<Box<Expr<R>>>,
    pub body: Vec<Stmt<R>>,
}

impl<R> Node for MatchCase<R> {
    const NAME: &'static str = "match_case";
    const FIELD_NAMES: &'static [&'static str] = &["pattern", "guard", "body"];
}

/// See also [pattern](https://docs.python.org/3/library/ast.html#ast.pattern)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum Pattern<R = TextRange> {
    MatchValue(PatternMatchValue<R>),
    MatchSingleton(PatternMatchSingleton<R>),
    MatchSequence(PatternMatchSequence<R>),
    MatchMapping(PatternMatchMapping<R>),
    MatchClass(PatternMatchClass<R>),
    MatchStar(PatternMatchStar<R>),
    MatchAs(PatternMatchAs<R>),
    MatchOr(PatternMatchOr<R>),
}

/// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchValue<R = TextRange> {
    pub range: R,
    pub value: Box<Expr<R>>,
}

impl<R> Node for PatternMatchValue<R> {
    const NAME: &'static str = "MatchValue";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<PatternMatchValue<R>> for Pattern<R> {
    fn from(payload: PatternMatchValue<R>) -> Self {
        Pattern::MatchValue(payload)
    }
}
impl<R> From<PatternMatchValue<R>> for Ast<R> {
    fn from(payload: PatternMatchValue<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchSingleton](https://docs.python.org/3/library/ast.html#ast.MatchSingleton)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchSingleton<R = TextRange> {
    pub range: R,
    pub value: Constant,
}

impl<R> Node for PatternMatchSingleton<R> {
    const NAME: &'static str = "MatchSingleton";
    const FIELD_NAMES: &'static [&'static str] = &["value"];
}
impl<R> From<PatternMatchSingleton<R>> for Pattern<R> {
    fn from(payload: PatternMatchSingleton<R>) -> Self {
        Pattern::MatchSingleton(payload)
    }
}
impl<R> From<PatternMatchSingleton<R>> for Ast<R> {
    fn from(payload: PatternMatchSingleton<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchSequence](https://docs.python.org/3/library/ast.html#ast.MatchSequence)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchSequence<R = TextRange> {
    pub range: R,
    pub patterns: Vec<Pattern<R>>,
}

impl<R> Node for PatternMatchSequence<R> {
    const NAME: &'static str = "MatchSequence";
    const FIELD_NAMES: &'static [&'static str] = &["patterns"];
}
impl<R> From<PatternMatchSequence<R>> for Pattern<R> {
    fn from(payload: PatternMatchSequence<R>) -> Self {
        Pattern::MatchSequence(payload)
    }
}
impl<R> From<PatternMatchSequence<R>> for Ast<R> {
    fn from(payload: PatternMatchSequence<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchMapping](https://docs.python.org/3/library/ast.html#ast.MatchMapping)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchMapping<R = TextRange> {
    pub range: R,
    pub keys: Vec<Expr<R>>,
    pub patterns: Vec<Pattern<R>>,
    pub rest: Option<Identifier>,
}

impl<R> Node for PatternMatchMapping<R> {
    const NAME: &'static str = "MatchMapping";
    const FIELD_NAMES: &'static [&'static str] = &["keys", "patterns", "rest"];
}
impl<R> From<PatternMatchMapping<R>> for Pattern<R> {
    fn from(payload: PatternMatchMapping<R>) -> Self {
        Pattern::MatchMapping(payload)
    }
}
impl<R> From<PatternMatchMapping<R>> for Ast<R> {
    fn from(payload: PatternMatchMapping<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchClass](https://docs.python.org/3/library/ast.html#ast.MatchClass)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchClass<R = TextRange> {
    pub range: R,
    pub cls: Box<Expr<R>>,
    pub patterns: Vec<Pattern<R>>,
    pub kwd_attrs: Vec<Identifier>,
    pub kwd_patterns: Vec<Pattern<R>>,
}

impl<R> Node for PatternMatchClass<R> {
    const NAME: &'static str = "MatchClass";
    const FIELD_NAMES: &'static [&'static str] = &["cls", "patterns", "kwd_attrs", "kwd_patterns"];
}
impl<R> From<PatternMatchClass<R>> for Pattern<R> {
    fn from(payload: PatternMatchClass<R>) -> Self {
        Pattern::MatchClass(payload)
    }
}
impl<R> From<PatternMatchClass<R>> for Ast<R> {
    fn from(payload: PatternMatchClass<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchStar](https://docs.python.org/3/library/ast.html#ast.MatchStar)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchStar<R = TextRange> {
    pub range: R,
    pub name: Option<Identifier>,
}

impl<R> Node for PatternMatchStar<R> {
    const NAME: &'static str = "MatchStar";
    const FIELD_NAMES: &'static [&'static str] = &["name"];
}
impl<R> From<PatternMatchStar<R>> for Pattern<R> {
    fn from(payload: PatternMatchStar<R>) -> Self {
        Pattern::MatchStar(payload)
    }
}
impl<R> From<PatternMatchStar<R>> for Ast<R> {
    fn from(payload: PatternMatchStar<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchAs](https://docs.python.org/3/library/ast.html#ast.MatchAs)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchAs<R = TextRange> {
    pub range: R,
    pub pattern: Option<Box<Pattern<R>>>,
    pub name: Option<Identifier>,
}

impl<R> Node for PatternMatchAs<R> {
    const NAME: &'static str = "MatchAs";
    const FIELD_NAMES: &'static [&'static str] = &["pattern", "name"];
}
impl<R> From<PatternMatchAs<R>> for Pattern<R> {
    fn from(payload: PatternMatchAs<R>) -> Self {
        Pattern::MatchAs(payload)
    }
}
impl<R> From<PatternMatchAs<R>> for Ast<R> {
    fn from(payload: PatternMatchAs<R>) -> Self {
        Pattern::from(payload).into()
    }
}

/// See also [MatchOr](https://docs.python.org/3/library/ast.html#ast.MatchOr)
#[derive(Clone, Debug, PartialEq)]
pub struct PatternMatchOr<R = TextRange> {
    pub range: R,
    pub patterns: Vec<Pattern<R>>,
}

impl<R> Node for PatternMatchOr<R> {
    const NAME: &'static str = "MatchOr";
    const FIELD_NAMES: &'static [&'static str] = &["patterns"];
}
impl<R> From<PatternMatchOr<R>> for Pattern<R> {
    fn from(payload: PatternMatchOr<R>) -> Self {
        Pattern::MatchOr(payload)
    }
}
impl<R> From<PatternMatchOr<R>> for Ast<R> {
    fn from(payload: PatternMatchOr<R>) -> Self {
        Pattern::from(payload).into()
    }
}

impl<R> Node for Pattern<R> {
    const NAME: &'static str = "pattern";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [type_ignore](https://docs.python.org/3/library/ast.html#ast.type_ignore)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum TypeIgnore<R = TextRange> {
    TypeIgnore(TypeIgnoreTypeIgnore<R>),
}

/// See also [TypeIgnore](https://docs.python.org/3/library/ast.html#ast.TypeIgnore)
#[derive(Clone, Debug, PartialEq)]
pub struct TypeIgnoreTypeIgnore<R = TextRange> {
    pub range: OptionalRange<R>,
    pub lineno: Int,
    pub tag: String,
}

impl<R> Node for TypeIgnoreTypeIgnore<R> {
    const NAME: &'static str = "TypeIgnore";
    const FIELD_NAMES: &'static [&'static str] = &["lineno", "tag"];
}
impl<R> From<TypeIgnoreTypeIgnore<R>> for TypeIgnore<R> {
    fn from(payload: TypeIgnoreTypeIgnore<R>) -> Self {
        TypeIgnore::TypeIgnore(payload)
    }
}
impl<R> From<TypeIgnoreTypeIgnore<R>> for Ast<R> {
    fn from(payload: TypeIgnoreTypeIgnore<R>) -> Self {
        TypeIgnore::from(payload).into()
    }
}

impl<R> Node for TypeIgnore<R> {
    const NAME: &'static str = "type_ignore";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum TypeParam<R = TextRange> {
    TypeVar(TypeParamTypeVar<R>),
    ParamSpec(TypeParamParamSpec<R>),
    TypeVarTuple(TypeParamTypeVarTuple<R>),
}

/// See also [TypeVar](https://docs.python.org/3/library/ast.html#ast.TypeVar)
#[derive(Clone, Debug, PartialEq)]
pub struct TypeParamTypeVar<R = TextRange> {
    pub range: R,
    pub name: Identifier,
    pub bound: Option<Box<Expr<R>>>,
}

impl<R> Node for TypeParamTypeVar<R> {
    const NAME: &'static str = "TypeVar";
    const FIELD_NAMES: &'static [&'static str] = &["name", "bound"];
}
impl<R> From<TypeParamTypeVar<R>> for TypeParam<R> {
    fn from(payload: TypeParamTypeVar<R>) -> Self {
        TypeParam::TypeVar(payload)
    }
}
impl<R> From<TypeParamTypeVar<R>> for Ast<R> {
    fn from(payload: TypeParamTypeVar<R>) -> Self {
        TypeParam::from(payload).into()
    }
}

/// See also [ParamSpec](https://docs.python.org/3/library/ast.html#ast.ParamSpec)
#[derive(Clone, Debug, PartialEq)]
pub struct TypeParamParamSpec<R = TextRange> {
    pub range: R,
    pub name: Identifier,
}

impl<R> Node for TypeParamParamSpec<R> {
    const NAME: &'static str = "ParamSpec";
    const FIELD_NAMES: &'static [&'static str] = &["name"];
}
impl<R> From<TypeParamParamSpec<R>> for TypeParam<R> {
    fn from(payload: TypeParamParamSpec<R>) -> Self {
        TypeParam::ParamSpec(payload)
    }
}
impl<R> From<TypeParamParamSpec<R>> for Ast<R> {
    fn from(payload: TypeParamParamSpec<R>) -> Self {
        TypeParam::from(payload).into()
    }
}

/// See also [TypeVarTuple](https://docs.python.org/3/library/ast.html#ast.TypeVarTuple)
#[derive(Clone, Debug, PartialEq)]
pub struct TypeParamTypeVarTuple<R = TextRange> {
    pub range: R,
    pub name: Identifier,
}

impl<R> Node for TypeParamTypeVarTuple<R> {
    const NAME: &'static str = "TypeVarTuple";
    const FIELD_NAMES: &'static [&'static str] = &["name"];
}
impl<R> From<TypeParamTypeVarTuple<R>> for TypeParam<R> {
    fn from(payload: TypeParamTypeVarTuple<R>) -> Self {
        TypeParam::TypeVarTuple(payload)
    }
}
impl<R> From<TypeParamTypeVarTuple<R>> for Ast<R> {
    fn from(payload: TypeParamTypeVarTuple<R>) -> Self {
        TypeParam::from(payload).into()
    }
}

impl<R> Node for TypeParam<R> {
    const NAME: &'static str = "type_param";
    const FIELD_NAMES: &'static [&'static str] = &[];
}

/// An alternative type of AST `arguments`. This is parser-friendly and human-friendly definition of function arguments.
/// This form also has advantage to implement pre-order traverse.
/// `defaults` and `kw_defaults` fields are removed and the default values are placed under each `arg_with_default` typed argument.
/// `vararg` and `kwarg` are still typed as `arg` because they never can have a default value.
///
/// The matching Python style AST type is [PythonArguments]. While [PythonArguments] has ordered `kwonlyargs` fields by
/// default existence, [Arguments] has location-ordered kwonlyargs fields.
///
/// NOTE: This type is different from original Python AST.

#[derive(Clone, Debug, PartialEq)]
pub struct Arguments<R = TextRange> {
    pub range: OptionalRange<R>,
    pub posonlyargs: Vec<ArgWithDefault<R>>,
    pub args: Vec<ArgWithDefault<R>>,
    pub vararg: Option<Box<Arg<R>>>,
    pub kwonlyargs: Vec<ArgWithDefault<R>>,
    pub kwarg: Option<Box<Arg<R>>>,
}

impl<R> Node for Arguments<R> {
    const NAME: &'static str = "alt:arguments";
    const FIELD_NAMES: &'static [&'static str] =
        &["posonlyargs", "args", "vararg", "kwonlyargs", "kwarg"];
}

/// An alternative type of AST `arg`. This is used for each function argument that might have a default value.
/// Used by `Arguments` original type.
///
/// NOTE: This type is different from original Python AST.

#[derive(Clone, Debug, PartialEq)]
pub struct ArgWithDefault<R = TextRange> {
    pub range: OptionalRange<R>,
    pub def: Arg<R>,
    pub default: Option<Box<Expr<R>>>,
}

impl<R> Node for ArgWithDefault<R> {
    const NAME: &'static str = "arg_with_default";
    const FIELD_NAMES: &'static [&'static str] = &["def", "default"];
}
