newtypedecl 0.0.1

declarative newtype macro
Documentation
* `fn name(params)`
* `fn name`
* `fn name(&t vs t)`
* `fn name`







The macro generates a lot of code for you. This code generation can be customized by the user
with an abbreviated syntax.

The newtype macro can generate 

`!default fn`
`!default impl`



### Functions and Methods

A `impl` block for the defined struct is generated. This contains automatically generated
functions. The user can override these functions by providing a custom implementation,
suppress the generation of these functions or implement custom functions.


### Traits

A set of traits will be automatically implemented. The user can enable or suppress these
implementations or provide custom implementations. Implementation of other traits is also
possible and using an abbreviated syntax for general cases.

// impl<T: ?Sized> AsRef<T> for Example
// where
//     Inner: AsRef<T>,
// {
//     fn as_ref(&self) -> &T {
//         self.0.as_ref()
//     }
// }

## DWIM

While the macro aims for generating code in a convenient way, it would only do what a
programmer does. The generated newtype struct is easy to extend by conventional `impl` and
`impl Trait` blocks. Some defaults are opinionated but can be overridden by the user.

# Example

The simplest case lets you use it like this:

```rust,ignore
use newtypedecl::newtype;

newtype! {
    pub struct Example(String)
}
```

This will generate the following code for you:

```rust,ignore
#[repr(transparent)]
pub struct Example(String);

impl Example {
    pub fn new(s: String) -> Self {
        Self(s)
    }

    pub fn into_inner(t: Self) -> String {
        t.0
    }
}

<!-- impl AsRef<String> for Example {
 !--     fn as_ref(&self) -> &str {
 !--         self.0.as_ref()
 !--     }
 !-- }
 !-- 
 !-- impl AsMut<str> for Example {
 !--     fn as_mut(&mut self) -> &mut str {
 !--         self.0.as_mut()
 !--     }
 !-- }
 !-- 
 !-- impl Borrow<str> for Example {
 !--     fn borrow(&self) -> &str {
 !--         self.0.borrow()
 !--     }
 !-- }
 !-- 
 !-- impl BorrowMut<str> for Example {
 !--     fn borrow_mut(&mut self) -> &mut str {
 !--         self.0.borrow_mut()
 !--     }
 !-- }
 !-- 
 !-- impl From<String> for Example {
 !--     fn from(s: String) -> Self {
 !--         Self(s)
 !--     }
 !-- } -->
```

A more complex example is:

```rust,ignore
#[macro_use]
use newtypedecl::newtype;

newtype! {
    // Attributes are passed to the generated struct
    /// This includes doc comments
    #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Example(String) {
        // provide a `new` function that overrides the automatic implementation
        // PLANNED: pub const fn new() -> Self {Self(String::new())}

        // suppress the generation of the `take` function
        // PLANNED: !fn take;
        
        // generates a method `push_str` that forwards to `String::push_str()`
        // PLANNED: pub fn push_str(&self, s: &str);
        
        // implement a custom method
        /* PLANNED: pub fn hello(&self) {
            println!("Hello {}!", self.0);
        } */
        
        // suppress the automatic implementation of the `From` trait
        // PLANNED: !impl From;
    }
}
```
The code generator tries to make educated guesses (heuristics) by looking at the newtype
definition. For example depending on if the type is `Clone`, `Copy` or `Default` and if the
`From` trait is implemented the `fn new` with either take no parameter (Default + From
defined), or a parameter by value (no Clone and no Copy) or reference (Clone or Copy).
These heuristics are not perfect, for example the Inner type




A initial implementaiton of the product syntax was done by [Lukas Kalbertodt][lukas] in
[issue #1][issue1] and [PR #2][pr2]. The current implementation is a rewrite of the original
code. The original implementation was not compatible with the newtype completion engine and
had some other issues. The new implementation is more robust and has a better error reporting.