mirror of https://git.sr.ht/~stygianentity/bincode
Added more documentation to derive/src/generate
This commit is contained in:
parent
4b25114c59
commit
baad206c6c
|
|
@ -24,21 +24,7 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
/// Add a generic parameter. Keep in mind that will *not* work for lifetimes.
|
||||||
#[doc(hidden)]
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn for_test() -> Self {
|
|
||||||
Self {
|
|
||||||
generate: None,
|
|
||||||
name: String::new(),
|
|
||||||
lifetime_and_generics: Vec::new(),
|
|
||||||
self_arg: FnSelfArg::None,
|
|
||||||
args: Vec::new(),
|
|
||||||
return_type: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a generic parameter. Keep in mind that this is *not* a valid lifetime.
|
|
||||||
///
|
///
|
||||||
/// `dependencies` are the optional dependencies of the parameter.
|
/// `dependencies` are the optional dependencies of the parameter.
|
||||||
///
|
///
|
||||||
|
|
@ -61,21 +47,53 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the value for `self`. See [FnSelfArg] for more information.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let mut builder: FnBuilder = ...;
|
||||||
|
/// // static function by default
|
||||||
|
/// builder.with_self_arg(FnSelfArg::RefSelf); // fn foo(&self)
|
||||||
|
/// ```
|
||||||
pub fn with_self_arg(mut self, self_arg: FnSelfArg) -> Self {
|
pub fn with_self_arg(mut self, self_arg: FnSelfArg) -> Self {
|
||||||
self.self_arg = self_arg;
|
self.self_arg = self_arg;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an argument with a `name` and a `ty`.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let mut builder: FnBuilder = ...;
|
||||||
|
/// // fn foo();
|
||||||
|
/// builder
|
||||||
|
/// .with_arg("a", "u32") // fn foo(a: u32)
|
||||||
|
/// .with_arg("b", "u32"); // fn foo(a: u32, b: u32)
|
||||||
|
/// ```
|
||||||
pub fn with_arg(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
|
pub fn with_arg(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
|
||||||
self.args.push((name.into(), ty.into()));
|
self.args.push((name.into(), ty.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the return type for the function. By default the function will have no return type.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let mut builder: FnBuilder = ...;
|
||||||
|
/// // fn foo()
|
||||||
|
/// builder.with_return_type("u32"); // fn foo() -> u32
|
||||||
|
/// ```
|
||||||
pub fn with_return_type(mut self, ret_type: impl Into<String>) -> Self {
|
pub fn with_return_type(mut self, ret_type: impl Into<String>) -> Self {
|
||||||
self.return_type = Some(ret_type.into());
|
self.return_type = Some(ret_type.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Complete the function definition. This function takes a callback that will form the body of the function.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let mut builder: FnBuilder = ...;
|
||||||
|
/// // fn foo()
|
||||||
|
/// builder.body(|b| {
|
||||||
|
/// b.push_parsed("println!(\"hello world\");");
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
pub fn body(self, body_builder: impl FnOnce(&mut StreamBuilder)) {
|
pub fn body(self, body_builder: impl FnOnce(&mut StreamBuilder)) {
|
||||||
let FnBuilder {
|
let FnBuilder {
|
||||||
mut generate,
|
mut generate,
|
||||||
|
|
@ -141,9 +159,20 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `self` argument of a function
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum FnSelfArg {
|
pub enum FnSelfArg {
|
||||||
|
/// No `self` argument. The function will be a static function.
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
/// `self`. The function will consume self.
|
||||||
|
TakeSelf,
|
||||||
|
|
||||||
|
/// `&self`. The function will take self by reference.
|
||||||
RefSelf,
|
RefSelf,
|
||||||
|
|
||||||
|
/// `&mut self`. The function will take self by mutable reference.
|
||||||
|
MutSelf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FnSelfArg {
|
impl FnSelfArg {
|
||||||
|
|
@ -151,10 +180,18 @@ impl FnSelfArg {
|
||||||
let mut builder = StreamBuilder::new();
|
let mut builder = StreamBuilder::new();
|
||||||
match self {
|
match self {
|
||||||
Self::None => return None,
|
Self::None => return None,
|
||||||
|
Self::TakeSelf => {
|
||||||
|
builder.ident_str("self");
|
||||||
|
}
|
||||||
Self::RefSelf => {
|
Self::RefSelf => {
|
||||||
builder.punct('&');
|
builder.punct('&');
|
||||||
builder.ident_str("self");
|
builder.ident_str("self");
|
||||||
}
|
}
|
||||||
|
Self::MutSelf => {
|
||||||
|
builder.punct('&');
|
||||||
|
builder.ident_str("mut");
|
||||||
|
builder.ident_str("self");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(builder)
|
Some(builder)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,22 @@ impl Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the name for the struct or enum that this is going to be implemented on.
|
||||||
pub fn target_name(&self) -> &Ident {
|
pub fn target_name(&self) -> &Ident {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate an `for <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
||||||
pub fn impl_for<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
pub fn impl_for<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
||||||
ImplFor::new(self, trait_name)
|
ImplFor::new(self, trait_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate an `for <'__de> <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
||||||
pub fn impl_for_with_de_lifetime<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
pub fn impl_for_with_de_lifetime<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
||||||
ImplFor::new_with_de_lifetime(self, trait_name)
|
ImplFor::new_with_de_lifetime(self, trait_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the struct or enum has lifetimes.
|
||||||
pub fn has_lifetimes(&self) -> bool {
|
pub fn has_lifetimes(&self) -> bool {
|
||||||
self.generics
|
self.generics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -43,8 +47,9 @@ impl Generator {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume the contents of this generator. This *must* be called, or else the generator will panic on drop.
|
||||||
pub fn take_stream(mut self) -> TokenStream {
|
pub fn take_stream(mut self) -> TokenStream {
|
||||||
std::mem::take(&mut self.stream.stream)
|
std::mem::take(&mut self.stream).stream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ impl<'a> ImplFor<'a> {
|
||||||
Self { generator, group }
|
Self { generator, group }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a function to the trait implementation
|
||||||
pub fn generate_fn<'b>(&'b mut self, name: &str) -> FnBuilder<'a, 'b> {
|
pub fn generate_fn<'b>(&'b mut self, name: &str) -> FnBuilder<'a, 'b> {
|
||||||
FnBuilder::new(self, name)
|
FnBuilder::new(self, name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::prelude::{
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
/// A helper struct build around a [TokenStream] to make it easier to build code.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct StreamBuilder {
|
pub struct StreamBuilder {
|
||||||
|
|
@ -10,24 +11,31 @@ pub struct StreamBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StreamBuilder {
|
impl StreamBuilder {
|
||||||
|
/// Generate a new StreamBuilder
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stream: TokenStream::new(),
|
stream: TokenStream::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add multiple `TokenTree` items to the stream.
|
||||||
pub fn extend(&mut self, item: impl IntoIterator<Item = TokenTree>) {
|
pub fn extend(&mut self, item: impl IntoIterator<Item = TokenTree>) {
|
||||||
self.stream.extend(item);
|
self.stream.extend(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Append another StreamBuilder to the current StreamBuilder.
|
||||||
pub fn append(&mut self, builder: StreamBuilder) {
|
pub fn append(&mut self, builder: StreamBuilder) {
|
||||||
self.stream.extend(builder.stream);
|
self.stream.extend(builder.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push a single token to the stream.
|
||||||
pub fn push(&mut self, item: impl Into<TokenTree>) {
|
pub fn push(&mut self, item: impl Into<TokenTree>) {
|
||||||
self.stream.extend([item.into()]);
|
self.stream.extend([item.into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to parse the given string as valid Rust code, and append the parsed result to the internal stream.
|
||||||
|
///
|
||||||
|
/// Currently panics if the string could not be parsed as valid Rust code.
|
||||||
pub fn push_parsed(&mut self, item: impl AsRef<str>) {
|
pub fn push_parsed(&mut self, item: impl AsRef<str>) {
|
||||||
self.stream
|
self.stream
|
||||||
.extend(TokenStream::from_str(item.as_ref()).unwrap_or_else(|e| {
|
.extend(TokenStream::from_str(item.as_ref()).unwrap_or_else(|e| {
|
||||||
|
|
@ -39,10 +47,12 @@ impl StreamBuilder {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push a single ident to the stream. An ident is any worse that a code file may contain, e.g. `fn`, `struct`, `where`, names of functions and structs, etc.
|
||||||
pub fn ident(&mut self, ident: Ident) {
|
pub fn ident(&mut self, ident: Ident) {
|
||||||
self.stream.extend([TokenTree::Ident(ident)]);
|
self.stream.extend([TokenTree::Ident(ident)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push a single ident to the stream. An ident is any worse that a code file may contain, e.g. `fn`, `struct`, `where`, names of functions and structs, etc.
|
||||||
pub fn ident_str(&mut self, ident: impl AsRef<str>) {
|
pub fn ident_str(&mut self, ident: impl AsRef<str>) {
|
||||||
self.stream.extend([TokenTree::Ident(Ident::new(
|
self.stream.extend([TokenTree::Ident(Ident::new(
|
||||||
ident.as_ref(),
|
ident.as_ref(),
|
||||||
|
|
@ -50,6 +60,9 @@ impl StreamBuilder {
|
||||||
))]);
|
))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a group. A group is any block surrounded by `{ .. }`, `[ .. ]` or `( .. )`.
|
||||||
|
///
|
||||||
|
/// `delim` indicates which group it is. The `inner` callback is used to fill the contents of the group.
|
||||||
pub fn group(&mut self, delim: Delimiter, inner: impl FnOnce(&mut StreamBuilder)) {
|
pub fn group(&mut self, delim: Delimiter, inner: impl FnOnce(&mut StreamBuilder)) {
|
||||||
let mut stream = StreamBuilder::new();
|
let mut stream = StreamBuilder::new();
|
||||||
inner(&mut stream);
|
inner(&mut stream);
|
||||||
|
|
@ -57,11 +70,18 @@ impl StreamBuilder {
|
||||||
.extend([TokenTree::Group(Group::new(delim, stream.stream))]);
|
.extend([TokenTree::Group(Group::new(delim, stream.stream))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a single punctuation to the stream. Puncts are single-character tokens like `.`, `<`, `#`, etc
|
||||||
|
///
|
||||||
|
/// Note that this should not be used for multi-punct constructions like `::` or `->`. For that use [puncts] instead.
|
||||||
pub fn punct(&mut self, p: char) {
|
pub fn punct(&mut self, p: char) {
|
||||||
self.stream
|
self.stream
|
||||||
.extend([TokenTree::Punct(Punct::new(p, Spacing::Alone))]);
|
.extend([TokenTree::Punct(Punct::new(p, Spacing::Alone))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add multiple punctuations to the stream. Multi punct tokens are e.g. `::`, `->` and `=>`.
|
||||||
|
///
|
||||||
|
/// Note that this is the only way to add multi punct tokens.
|
||||||
|
/// If you were to use [punct] to insert `->` it would be inserted as `-` and then `>`, and not form a single token. Rust would interpret this as a "minus sign and then a greater than sign", not as a single arrow.
|
||||||
pub fn puncts(&mut self, puncts: &str) {
|
pub fn puncts(&mut self, puncts: &str) {
|
||||||
self.stream.extend(
|
self.stream.extend(
|
||||||
puncts
|
puncts
|
||||||
|
|
@ -70,12 +90,29 @@ impl StreamBuilder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a lifetime to the stream.
|
||||||
|
///
|
||||||
|
/// Note that this is the only way to add lifetimes, if you were to do:
|
||||||
|
/// ```ignore
|
||||||
|
/// builder.punct('\'');
|
||||||
|
/// builder.ident_str("static");
|
||||||
|
/// ```
|
||||||
|
/// It would not add `'static`, but instead it would add `' static` as seperate tokens, and the lifetime would not work.
|
||||||
pub fn lifetime(&mut self, lt: Ident) {
|
pub fn lifetime(&mut self, lt: Ident) {
|
||||||
self.stream.extend([
|
self.stream.extend([
|
||||||
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
|
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
|
||||||
TokenTree::Ident(lt),
|
TokenTree::Ident(lt),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a lifetime to the stream.
|
||||||
|
///
|
||||||
|
/// Note that this is the only way to add lifetimes, if you were to do:
|
||||||
|
/// ```ignore
|
||||||
|
/// builder.punct('\'');
|
||||||
|
/// builder.ident_str("static");
|
||||||
|
/// ```
|
||||||
|
/// It would not add `'static`, but instead it would add `' static` as seperate tokens, and the lifetime would not work.
|
||||||
pub fn lifetime_str(&mut self, lt: &str) {
|
pub fn lifetime_str(&mut self, lt: &str) {
|
||||||
self.stream.extend([
|
self.stream.extend([
|
||||||
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
|
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
|
||||||
|
|
@ -83,21 +120,25 @@ impl StreamBuilder {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a literal string (`&'static str`) to the stream.
|
||||||
pub fn lit_str(&mut self, str: impl AsRef<str>) {
|
pub fn lit_str(&mut self, str: impl AsRef<str>) {
|
||||||
self.stream
|
self.stream
|
||||||
.extend([TokenTree::Literal(Literal::string(str.as_ref()))]);
|
.extend([TokenTree::Literal(Literal::string(str.as_ref()))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an `u32` value to the stream.
|
||||||
pub fn lit_u32(&mut self, val: u32) {
|
pub fn lit_u32(&mut self, val: u32) {
|
||||||
self.stream
|
self.stream
|
||||||
.extend([TokenTree::Literal(Literal::u32_unsuffixed(val))]);
|
.extend([TokenTree::Literal(Literal::u32_unsuffixed(val))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an `usize` value to the stream.
|
||||||
pub fn lit_usize(&mut self, val: usize) {
|
pub fn lit_usize(&mut self, val: usize) {
|
||||||
self.stream
|
self.stream
|
||||||
.extend([TokenTree::Literal(Literal::usize_unsuffixed(val))]);
|
.extend([TokenTree::Literal(Literal::usize_unsuffixed(val))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the given span on all tokens in the stream. This span is used by rust for e.g. compiler errors, to indicate the position of the error.
|
||||||
pub fn set_span_on_all_tokens(&mut self, span: Span) {
|
pub fn set_span_on_all_tokens(&mut self, span: Span) {
|
||||||
self.stream = std::mem::take(&mut self.stream)
|
self.stream = std::mem::take(&mut self.stream)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue