Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Lossless parsing for structs and ToTokens implementation. #53

@vldm

Description

@vldm

Hi! First of all thanks for a great project!.

In my pet project, i am parsing some context using syn-rsx, and trying to recreate part of token stream as input for other library. To recreate tokens i using quote!()\quote_spanned!() macros and found few problems:

  1. Only few elements implement ToTokens, so i need to implement it manually in my wrappers.
  2. Tokens that i hardcode and tokens from NodeElement semantically have different sites (call_site vs def_site vs mixed_site), and source file info, and if i understand correctly cannot be joined.

What do you think about modifying your implementation, so it will save original token stream inside struct

For example, instead of

pub struct NodeElement {
    /// Name of the element.
    pub name: NodeName,
    /// Attributes of the element node.
    pub attributes: Vec<Node>,
    /// Children of the element node.
    pub children: Vec<Node>,
    /// Source span of the element for error reporting.
    ///
    /// Note: This should cover the entire node in nightly, but is a "close
    /// enough" approximation in stable until [Span::join] is stabilized.
    pub span: Span,
}

You could have:

pub struct StartTag {
    pub less_sign: Token![<],
    pub tag_name: NodeName,
    pub attributes: Vec<Attribute>,
    pub solidus: Option<Token![/]>,
    pub great_sign: Token![>],
}
impl StartTag {
    pub fn is_self_closing(&self) -> bool {
        self.solidus.is_some()
    }
}

pub struct EndTag {
    pub less_sign: Token![<],
    pub solidus: Token![/],
    pub tag_name: NodeName,
    pub great_sign: Token![>],
}

pub struct NodeElement {
     pub start_tag: StartTag,
     pub end_tag: Option<EndTag>,
}

Benefits:

  • The same approach is used in syn library itself. So the code will look more idiomatically.
  • It allows you to implement parser fully on type - TypeDD aproach makes contracts more visible.
  • You can implement syn::Parse just by going and init every field in struct
  • Allows you to implement ToTokens (Spanned will be derived from this method) without introducing mixed site.
  • Also, you don't need to implement your own TryFrom<Struct> for String because TokenStream could be converted to text directly. But you still be able to implement fn safe_html_text for important types

Downside:

  • Its a breaking change.
  • ?Anything else

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions