pub fn concat(lhs: Box<Ast>, rhs: Box<Ast>) -> Box<Ast> {
    match (*lhs, *rhs) {
        (Ast::Concat(ref lconcat), Ast::Concat(ref rconcat)) => {
            Box::new(Ast::Concat(Concat {
                span: lconcat.span.with_end(rconcat.span.end),
                asts: {
                    let mut v = lconcat.asts.clone();
                    v.extend(rconcat.asts.clone());
                    v
                },
            }))
        }

        (Ast::Concat(ref lconcat), ref r) => Box::new(Ast::Concat(Concat {
            span: lconcat.span.with_end(r.span().end),
            asts: {
                let mut v = lconcat.asts.clone();
                v.push(r.clone());
                v
            },
        })),

        (ref l, Ast::Concat(ref rconcat)) => Box::new(Ast::Concat(Concat {
            span: l.span().with_end(rconcat.span.end),
            asts: {
                let mut v = vec![l.clone()];
                v.extend(rconcat.asts.clone());
                v
            },
        })),

        (l, r) => {
            // The regex crate has no public dependency on regex-syntax,
            // which means that we have no way to just pass an AST to
            // the regex engine for compilation. One of the issues with this
            // is that we will lose any structure in the AST which does not
            // have a textual representation. In particular:
            //
            //     concat( 'foo', alt('a', 'bar') )
            //
            // will pretty print as:
            //
            //     fooa|bar
            //
            // then parse as:
            //
            //     alt( 'fooa', 'bar' )
            //
            // which is obviously wrong. The solution is to inject a bunch
            // of non-capturing groups. Sad bois.
            Box::new(Ast::Concat(Concat {
                span: l.span().with_end(r.span().end),
                asts: vec![
                    noncapturing_group(Box::new(l)),
                    noncapturing_group(Box::new(r)),
                ],
            }))
        }
    }
}
//
// The fact that regex_syntax::ast::Ast impls drop makes it really hard
// to avoid copying stuff that I don't think I should have to copy. For
// now I'm going to have to just bite the bullet, but eventually I may
// have to write my own regex AST type that does not come with a custom
// Drop. It may also be worthwhile to talk through the issue with
// @burntsushi.
//
The fact that regex_syntax::ast::Ast impls drop makes it really hard
to avoid copying stuff that I don't think I should have to copy. For
now I'm going to have to just bite the bullet, but eventually I may
have to write my own regex AST type that does not come with a custom
Drop. It may also be worthwhile to talk through the issue with
@burntsushi.
The fact that regex_syntax :: ast :: Ast impls drop makes it really hard to avoid copying stuff that I don ' t think I should have to copy . For now I ' m going to have to just bite the bullet but eventually I may have to write my own regex AST type that does not come with a custom Drop . It may also be worthwhile to talk through the issue with @burntsushi .
pub fn concat(lhs: Box<Ast>, rhs: Box<Ast>) -> Box<Ast> {
    match (*lhs, *rhs) {
        (Ast::Concat(ref lconcat), Ast::Concat(ref rconcat)) => {
            Box::new(Ast::Concat(Concat {
                span: lconcat.span.with_end(rconcat.span.end),
                asts: {
                    let mut v = lconcat.asts.clone();
                    v.extend(rconcat.asts.clone());
                    v
                },
            }))
        }
        (Ast::Concat(ref lconcat), ref r) => Box::new(Ast::Concat(Concat {
            span: lconcat.span.with_end(r.span().end),
            asts: {
                let mut v = lconcat.asts.clone();
                v.push(r.clone());
                v
            },
        })),
        (ref l, Ast::Concat(ref rconcat)) => Box::new(Ast::Concat(Concat {
            span: l.span().with_end(rconcat.span.end),
            asts: {
                let mut v = vec![l.clone()];
                v.extend(rconcat.asts.clone());
                v
            },
        })),
        (l, r) => {
            // The regex crate has no public dependency on regex-syntax,
            // which means that we have no way to just pass an AST to
            // the regex engine for compilation. One of the issues with this
            // is that we will lose any structure in the AST which does not
            // have a textual representation. In particular:
            //
            //     concat( 'foo', alt('a', 'bar') )
            //
            // will pretty print as:
            //
            //     fooa|bar
            //
            // then parse as:
            //
            //     alt( 'fooa', 'bar' )
            //
            // which is obviously wrong. The solution is to inject a bunch
            // of non-capturing groups. Sad bois.
            Box::new(Ast::Concat(Concat {
                span: l.span().with_end(r.span().end),
                asts: vec![
                    noncapturing_group(Box::new(l)),
                    noncapturing_group(Box::new(r)),
                ],
            }))
        }
    }
}
pub fn concat ( lhs : Box < Ast > , rhs : Box < Ast > ) -> Box < Ast > { match ( * lhs , * rhs ) { ( Ast :: Concat ( ref lconcat ) , Ast :: Concat ( ref rconcat ) ) => { Box :: new ( Ast :: Concat ( Concat { span : lconcat . span . with_end ( rconcat . span . end ) , asts : { let mut v = lconcat . asts . clone ( ) ; v . extend ( rconcat . asts . clone ( ) ) ; v } , } ) ) } ( Ast :: Concat ( ref lconcat ) , ref r ) => Box :: new ( Ast :: Concat ( Concat { span : lconcat . span . with_end ( r . span ( ) . end ) , asts : { let mut v = lconcat . asts . clone ( ) ; v . push ( r . clone ( ) ) ; v } , } ) ) , ( ref l , Ast :: Concat ( ref rconcat ) ) => Box :: new ( Ast :: Concat ( Concat { span : l . span ( ) . with_end ( rconcat . span . end ) , asts : { let mut v = vec ! [ l clone ( ) ] ; v . extend ( rconcat . asts . clone ( ) ) ; v } , } ) ) , ( l , r ) => { // The regex crate has no public dependency on regex-syntax, // which means that we have no way to just pass an AST to // the regex engine for compilation. One of the issues with this // is that we will lose any structure in the AST which does not // have a textual representation. In particular: // //     concat( 'foo', alt('a', 'bar') ) // // will pretty print as: // //     fooa|bar // // then parse as: // //     alt( 'fooa', 'bar' ) // // which is obviously wrong. The solution is to inject a bunch // of non-capturing groups. Sad bois. Box :: new ( Ast :: Concat ( Concat { span : l . span ( ) . with_end ( r . span ( ) . end ) , asts : vec ! [ noncapturing_group ( Box new ( l ) ) noncapturing_group ( Box new ( r ) ) ] , } ) ) } } }
The fact that regex_syntax::ast::Ast impls drop makes it really hard
to avoid copying stuff that I don't think I should have to copy.
The fact that regex_syntax :: ast :: Ast impls drop makes it really hard to avoid copying stuff that I don ' t think I should have to copy .
lhs
Box<Ast>
rhs
Box<Ast>