Code Monkey home page Code Monkey logo

derive-into-owned's Introduction

derive-into-owned

Build Status crates.io docs.rs

Rust procedural macros for deriving methods to help with working with types that contain Cow fields. Please note that this derive somewhat strangely works with duck-typing, at least for now. It was originally created to help me reduce the boilerplate with Cow types.

[derive(IntoOwned)] generates a method similar to:

use std::borrow::Cow;

struct Foo<'a> {
	field: Cow<'a, str>,
}

impl<'a> Foo<'a> {
	/// This method would be derived using #[derive(IntoOwned)]
	pub fn into_owned(self) -> Foo<'static> {
		Foo {
			field: Cow::Owned(self.field.into_owned()),
		}
	}
}

Originally based off of deep-clone-derive example but supports:

But wait there is even more! [derive(Borrowed)] generates a currently perhaps a bit limited version of a method like:

impl<'a> Foo<'a> {
	pub fn borrowed<'b>(&'b self) -> Foo<'b> {
		Foo {
			field: Cow::Borrowed(self.field.as_ref()),
		}
	}
}

Types with lifetimes

If your struct has a field with type Bar<'a> then Bar is assumed to have a method fn into_owned(self) -> Bar<'static>.

Note, there's no trait implementation expected because I didn't find one at the time and didn't think to create my own, assumed the Cow::into_owned might be getting an extension in standard library which never happened and so on.

Limitations

Currently deriving will fail miserably for at least but not limited to:

  • IntoOwned: borrowed fields like &'a str
  • Borrowed: struct/enum has more than one lifetime
  • both: arrays not supported
  • both: into_owned/borrowed types inside tuples inside vectors

Using with incompatible types results in not so understandable error messages. For example, given a struct:

#[derive(IntoOwned)]
struct Foo<'a> {
	field: &'a str,
}

The compiler error will be:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
 --> tests/does_not_compile.rs:4:10
  |
4 | #[derive(IntoOwned)]
  |          ^^^^^^^^^
  |
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 4:10...
 --> tests/does_not_compile.rs:4:10
  |
4 | #[derive(IntoOwned)]
  |          ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
 --> tests/does_not_compile.rs:4:10
  |
4 | #[derive(IntoOwned)]
  |          ^^^^^^^^^
  = note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected Foo<'static>, found Foo<'_>)
 --> tests/does_not_compile.rs:4:10
  |
4 | #[derive(IntoOwned)]
  |          ^^^^^^^^^
error: aborting due to previous error(s)

derive-into-owned's People

Contributors

detegr avatar hoodie avatar koivunej avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

derive-into-owned's Issues

Is this project still alive?

I stumbled upon this crate a few minutes ago and it seems to be exactly what I need (rust-lang/rust#71320).

This crate seems to be unmaintained (last commit in 2017) and before I create a new crate, I would like to kindly ask if I could maintain this crate?

`Option<Box<T<'a>>>` fields where `T`also has `into_owned`

I'm trying to use this for the SinkInfo<'a> in libpulse_binding (jnqnfe/pulse-binding-rust#44), but it has a field active_port: Option<Box<SinkPortInfo<'a>>>.

I guess to handle this, it would need to have logic to handle Boxes, like it handles Option, and FieldKind::resolve would have to be recursive to allow a Box inside an Option. I'm looking into how to implement this, since recursing in particular changes some things.

I guess it could also be helpful with complicated structs to have something like serde's deserialize_with to provide a custom into_owned for a field...

Add formal license file

From the Cargo.toml, the crate is MIT licensed, but there isn't a LICENSE file in the crate root with the full license. If it's not too much hassle, could that LICENSE file be added?

Provide traits for the given behavior

Hi,
it would be very useful if the derive macros where based on traits rather than implementing functions directly.
Is this out of scope? If yes i would probably start maintaining a fork which does that.

Thanks in advance

Why are you using this crate?

Over it's lifetime this crate has seen quite many downloads. For example, the 2021-10-19 had a huge (for this crate) 10k per day spike. I haven't used this crate myself in a few years but would be interested to know what are you using it for? If you are more than trying it out, does the duck typing aspect of $field.into_owned() give you any trouble, if so, how do you work around it?

I guess I'm mostly interested to hear if this should have some warning disclaimers on the README; I worry anyone trying this crate out quite quickly becomes aware of the limitations of it and the std::borrow::Cow. Would be happy to guide new folks to a blog post on std::borrow::Cow limitations if anyone knows a recent one.

support raw identifiers

Hi there,
thanks for providing this crate, it's super handy!
However I managed to find and edge-case that is not yet supported, but probably should be.

Currently you cant derive the Trait for structs that contain raw identifiers like this:

struct Thing {
    r#type: Cow<'_, str>;
}

They've been added in rust 1.3.0 and it seems like all that needs to be done is to update syn, since the version here is quite old.

I'd like to help but I've never build a proc-macro so far.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.