{"action":"created","comment":{"url":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments/60854199","id":60854199,"diff_hunk":"@@ -0,0 +1,422 @@\n+/// Implements the [`Insertable`][insertable] trait for a given struct. This\n+/// macro should be called with the name of the table you wish to use the struct\n+/// with, followed by the entire struct body.\n+///\n+/// [insertable]: prelude/trait.Insertable.html\n+///\n+/// # Example\n+///\n+/// ```no_run\n+/// # #[macro_use] extern crate diesel;\n+/// # table! { users { id -> Integer, name -> VarChar, hair_color -> Nullable<VarChar>, } }\n+/// struct NewUser<'a> {\n+///     name: &'a str,\n+///     hair_color: &'a str,\n+/// }\n+///\n+/// Insertable! {\n+///     (users)\n+///     struct NewUser<'a> {\n+///         name: &'a str,\n+///         hair_color: &'a str,\n+///     }\n+/// }\n+/// # fn main() {}\n+/// ```\n+///\n+/// To avoid copying your struct definition, you can use the\n+/// [custom_derive crate][custom_derive].\n+///\n+/// ```ignore\n+/// custom_derive! {\n+///     #[derive(Insertable(users))]\n+///     struct NewUser<'a> {\n+///         name: &'a str,\n+///         hair_color: &'a str,\n+///     }\n+/// }\n+/// ```\n+///\n+/// You can also use this macro with tuple structs, but *all* fields must be\n+/// annotated with `#[column_name(name)]`. Additionally, a trailing comma after\n+/// the last field is required.\n+///\n+/// ```no_run\n+/// # #[macro_use] extern crate diesel;\n+/// # table! { users { id -> Integer, name -> VarChar, hair_color -> Nullable<VarChar>, } }\n+/// struct NewUser<'a>(&'a str, Option<&'a str>);\n+///\n+/// Insertable! {\n+///     (users)\n+///     struct NewUser<'a>(\n+///         #[column_name(name)]\n+///         &'a str,\n+///         #[column_name(hair_color)]\n+///         Option<&'a str>,\n+///     );\n+/// }\n+/// # fn main() {}\n+/// ```\n+#[macro_export]\n+macro_rules! Insertable {\n+    // Strip meta items, pub (if present) and struct from definition\n+    (\n+        ($table_name:ident)\n+        $(#[$ignore:meta])*\n+        $(pub)* struct $($body:tt)*\n+    ) => {\n+        Insertable! {\n+            ($table_name)\n+            $($body)*\n+        }\n+    };\n+\n+    // Handle struct with lifetimes","path":"diesel/src/macros/insertable.rs","position":74,"original_position":74,"commit_id":"4e5fca99eeaec89abe59670c6b83b21c6ea064d9","original_commit_id":"4e5fca99eeaec89abe59670c6b83b21c6ea064d9","user":{"login":"sgrif","id":1529387,"avatar_url":"https://avatars.githubusercontent.com/u/1529387?v=3","gravatar_id":"","url":"https://api.github.com/users/sgrif","html_url":"https://github.com/sgrif","followers_url":"https://api.github.com/users/sgrif/followers","following_url":"https://api.github.com/users/sgrif/following{/other_user}","gists_url":"https://api.github.com/users/sgrif/gists{/gist_id}","starred_url":"https://api.github.com/users/sgrif/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgrif/subscriptions","organizations_url":"https://api.github.com/users/sgrif/orgs","repos_url":"https://api.github.com/users/sgrif/repos","events_url":"https://api.github.com/users/sgrif/events{/privacy}","received_events_url":"https://api.github.com/users/sgrif/received_events","type":"User","site_admin":false},"body":"Yup. Would normally restructure this code to not need it, but that's basically impossible with this type of macro.","created_at":"2016-04-24T23:51:00Z","updated_at":"2016-04-24T23:51:00Z","html_url":"https://github.com/diesel-rs/diesel/pull/303#discussion_r60854199","pull_request_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/303","_links":{"self":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments/60854199"},"html":{"href":"https://github.com/diesel-rs/diesel/pull/303#discussion_r60854199"},"pull_request":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/303"}}},"pull_request":{"url":"https://api.github.com/repos/diesel-rs/diesel/pulls/303","id":67653648,"html_url":"https://github.com/diesel-rs/diesel/pull/303","diff_url":"https://github.com/diesel-rs/diesel/pull/303.diff","patch_url":"https://github.com/diesel-rs/diesel/pull/303.patch","issue_url":"https://api.github.com/repos/diesel-rs/diesel/issues/303","number":303,"state":"open","locked":false,"title":"Provide a syntax extension free alternative to `#[insertable_into]`","user":{"login":"sgrif","id":1529387,"avatar_url":"https://avatars.githubusercontent.com/u/1529387?v=3","gravatar_id":"","url":"https://api.github.com/users/sgrif","html_url":"https://github.com/sgrif","followers_url":"https://api.github.com/users/sgrif/followers","following_url":"https://api.github.com/users/sgrif/following{/other_user}","gists_url":"https://api.github.com/users/sgrif/gists{/gist_id}","starred_url":"https://api.github.com/users/sgrif/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgrif/subscriptions","organizations_url":"https://api.github.com/users/sgrif/orgs","repos_url":"https://api.github.com/users/sgrif/repos","events_url":"https://api.github.com/users/sgrif/events{/privacy}","received_events_url":"https://api.github.com/users/sgrif/received_events","type":"User","site_admin":false},"body":"This provides a pure stable alternative to the `#[insertable_into]`\r\nannotation. The intention is to change the annotation to call this\r\nmacro, rather than `impl Insertable` directly. However, there are some\r\nunaddressed issues for that, and I will submit that as a separate PR to\r\nattempt to keep the PR size reasonable.\r\n\r\nThe tests for this are a bit messy, as the actual test body doesn't\r\nchange much -- Just the struct definition. I moved the most common case\r\nout into a macro, but I opted to just leave the duplication for the\r\nremaining 4-5 cases that didn't fit, instead of trying to make it so dry\r\nit chafes.\r\n\r\nWe will continue to support syntex as an option on stable, as we can\r\nprovide much better error messages from a procedural macro. I would like\r\nto improve the error messages in some cases if possible though (in\r\nparticular, we want to handle the case where a unit struct is passed or\r\nwhere a tuple struct has unannotated fields).\r\n\r\nThe structure of the macro is intended to be compatible with the\r\n`custom_derive` crate. This is untested, but will be fully tested once\r\nI've moved all our annotations to stable macros. The goal is for any\r\nstruct definition to be copy pasted into this macro, and the macro\r\nparses the struct body to create the proper implementation. For\r\nsufficiently large structs, we can hit the recursion limit, but there's\r\nreally no way around that. People will just need to bump the limit.\r\n\r\nOne case that this macro *doesn't* handle is when there are annotations\r\non struct fields other than `#[column_name]`. I had originally planned\r\nto handle these, but I realized that the only recognized annotation that\r\ncould be there on stable is `#[cfg]`, and we are *not* handling cfg\r\nattributes. We might handle that in the future, but it'd look *really*\r\nugly.\r\n\r\nRelated to #99","created_at":"2016-04-24T23:23:13Z","updated_at":"2016-04-24T23:51:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"914d77e42b27862a19e2462d78ef6ca4827bf1c9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/303/commits","review_comments_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/303/comments","review_comment_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments{/number}","comments_url":"https://api.github.com/repos/diesel-rs/diesel/issues/303/comments","statuses_url":"https://api.github.com/repos/diesel-rs/diesel/statuses/4e5fca99eeaec89abe59670c6b83b21c6ea064d9","head":{"label":"diesel-rs:sg-stable-insertable-into","ref":"sg-stable-insertable-into","sha":"4e5fca99eeaec89abe59670c6b83b21c6ea064d9","user":{"login":"diesel-rs","id":16763251,"avatar_url":"https://avatars.githubusercontent.com/u/16763251?v=3","gravatar_id":"","url":"https://api.github.com/users/diesel-rs","html_url":"https://github.com/diesel-rs","followers_url":"https://api.github.com/users/diesel-rs/followers","following_url":"https://api.github.com/users/diesel-rs/following{/other_user}","gists_url":"https://api.github.com/users/diesel-rs/gists{/gist_id}","starred_url":"https://api.github.com/users/diesel-rs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diesel-rs/subscriptions","organizations_url":"https://api.github.com/users/diesel-rs/orgs","repos_url":"https://api.github.com/users/diesel-rs/repos","events_url":"https://api.github.com/users/diesel-rs/events{/privacy}","received_events_url":"https://api.github.com/users/diesel-rs/received_events","type":"Organization","site_admin":false},"repo":{"id":41609775,"name":"diesel","full_name":"diesel-rs/diesel","owner":{"login":"diesel-rs","id":16763251,"avatar_url":"https://avatars.githubusercontent.com/u/16763251?v=3","gravatar_id":"","url":"https://api.github.com/users/diesel-rs","html_url":"https://github.com/diesel-rs","followers_url":"https://api.github.com/users/diesel-rs/followers","following_url":"https://api.github.com/users/diesel-rs/following{/other_user}","gists_url":"https://api.github.com/users/diesel-rs/gists{/gist_id}","starred_url":"https://api.github.com/users/diesel-rs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diesel-rs/subscriptions","organizations_url":"https://api.github.com/users/diesel-rs/orgs","repos_url":"https://api.github.com/users/diesel-rs/repos","events_url":"https://api.github.com/users/diesel-rs/events{/privacy}","received_events_url":"https://api.github.com/users/diesel-rs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/diesel-rs/diesel","description":"A safe, extensible ORM and Query Builder for Rust","fork":false,"url":"https://api.github.com/repos/diesel-rs/diesel","forks_url":"https://api.github.com/repos/diesel-rs/diesel/forks","keys_url":"https://api.github.com/repos/diesel-rs/diesel/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diesel-rs/diesel/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diesel-rs/diesel/teams","hooks_url":"https://api.github.com/repos/diesel-rs/diesel/hooks","issue_events_url":"https://api.github.com/repos/diesel-rs/diesel/issues/events{/number}","events_url":"https://api.github.com/repos/diesel-rs/diesel/events","assignees_url":"https://api.github.com/repos/diesel-rs/diesel/assignees{/user}","branches_url":"https://api.github.com/repos/diesel-rs/diesel/branches{/branch}","tags_url":"https://api.github.com/repos/diesel-rs/diesel/tags","blobs_url":"https://api.github.com/repos/diesel-rs/diesel/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diesel-rs/diesel/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diesel-rs/diesel/git/refs{/sha}","trees_url":"https://api.github.com/repos/diesel-rs/diesel/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diesel-rs/diesel/statuses/{sha}","languages_url":"https://api.github.com/repos/diesel-rs/diesel/languages","stargazers_url":"https://api.github.com/repos/diesel-rs/diesel/stargazers","contributors_url":"https://api.github.com/repos/diesel-rs/diesel/contributors","subscribers_url":"https://api.github.com/repos/diesel-rs/diesel/subscribers","subscription_url":"https://api.github.com/repos/diesel-rs/diesel/subscription","commits_url":"https://api.github.com/repos/diesel-rs/diesel/commits{/sha}","git_commits_url":"https://api.github.com/repos/diesel-rs/diesel/git/commits{/sha}","comments_url":"https://api.github.com/repos/diesel-rs/diesel/comments{/number}","issue_comment_url":"https://api.github.com/repos/diesel-rs/diesel/issues/comments{/number}","contents_url":"https://api.github.com/repos/diesel-rs/diesel/contents/{+path}","compare_url":"https://api.github.com/repos/diesel-rs/diesel/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diesel-rs/diesel/merges","archive_url":"https://api.github.com/repos/diesel-rs/diesel/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diesel-rs/diesel/downloads","issues_url":"https://api.github.com/repos/diesel-rs/diesel/issues{/number}","pulls_url":"https://api.github.com/repos/diesel-rs/diesel/pulls{/number}","milestones_url":"https://api.github.com/repos/diesel-rs/diesel/milestones{/number}","notifications_url":"https://api.github.com/repos/diesel-rs/diesel/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diesel-rs/diesel/labels{/name}","releases_url":"https://api.github.com/repos/diesel-rs/diesel/releases{/id}","deployments_url":"https://api.github.com/repos/diesel-rs/diesel/deployments","created_at":"2015-08-29T22:51:00Z","updated_at":"2016-04-24T18:59:23Z","pushed_at":"2016-04-24T23:46:42Z","git_url":"git://github.com/diesel-rs/diesel.git","ssh_url":"git@github.com:diesel-rs/diesel.git","clone_url":"https://github.com/diesel-rs/diesel.git","svn_url":"https://github.com/diesel-rs/diesel","homepage":"","size":4947,"stargazers_count":827,"watchers_count":827,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":49,"mirror_url":null,"open_issues_count":33,"forks":49,"open_issues":33,"watchers":827,"default_branch":"master"}},"base":{"label":"diesel-rs:master","ref":"master","sha":"9c8716caf4fa56766122f0cb14de74585bfed170","user":{"login":"diesel-rs","id":16763251,"avatar_url":"https://avatars.githubusercontent.com/u/16763251?v=3","gravatar_id":"","url":"https://api.github.com/users/diesel-rs","html_url":"https://github.com/diesel-rs","followers_url":"https://api.github.com/users/diesel-rs/followers","following_url":"https://api.github.com/users/diesel-rs/following{/other_user}","gists_url":"https://api.github.com/users/diesel-rs/gists{/gist_id}","starred_url":"https://api.github.com/users/diesel-rs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diesel-rs/subscriptions","organizations_url":"https://api.github.com/users/diesel-rs/orgs","repos_url":"https://api.github.com/users/diesel-rs/repos","events_url":"https://api.github.com/users/diesel-rs/events{/privacy}","received_events_url":"https://api.github.com/users/diesel-rs/received_events","type":"Organization","site_admin":false},"repo":{"id":41609775,"name":"diesel","full_name":"diesel-rs/diesel","owner":{"login":"diesel-rs","id":16763251,"avatar_url":"https://avatars.githubusercontent.com/u/16763251?v=3","gravatar_id":"","url":"https://api.github.com/users/diesel-rs","html_url":"https://github.com/diesel-rs","followers_url":"https://api.github.com/users/diesel-rs/followers","following_url":"https://api.github.com/users/diesel-rs/following{/other_user}","gists_url":"https://api.github.com/users/diesel-rs/gists{/gist_id}","starred_url":"https://api.github.com/users/diesel-rs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diesel-rs/subscriptions","organizations_url":"https://api.github.com/users/diesel-rs/orgs","repos_url":"https://api.github.com/users/diesel-rs/repos","events_url":"https://api.github.com/users/diesel-rs/events{/privacy}","received_events_url":"https://api.github.com/users/diesel-rs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/diesel-rs/diesel","description":"A safe, extensible ORM and Query Builder for Rust","fork":false,"url":"https://api.github.com/repos/diesel-rs/diesel","forks_url":"https://api.github.com/repos/diesel-rs/diesel/forks","keys_url":"https://api.github.com/repos/diesel-rs/diesel/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diesel-rs/diesel/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diesel-rs/diesel/teams","hooks_url":"https://api.github.com/repos/diesel-rs/diesel/hooks","issue_events_url":"https://api.github.com/repos/diesel-rs/diesel/issues/events{/number}","events_url":"https://api.github.com/repos/diesel-rs/diesel/events","assignees_url":"https://api.github.com/repos/diesel-rs/diesel/assignees{/user}","branches_url":"https://api.github.com/repos/diesel-rs/diesel/branches{/branch}","tags_url":"https://api.github.com/repos/diesel-rs/diesel/tags","blobs_url":"https://api.github.com/repos/diesel-rs/diesel/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diesel-rs/diesel/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diesel-rs/diesel/git/refs{/sha}","trees_url":"https://api.github.com/repos/diesel-rs/diesel/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diesel-rs/diesel/statuses/{sha}","languages_url":"https://api.github.com/repos/diesel-rs/diesel/languages","stargazers_url":"https://api.github.com/repos/diesel-rs/diesel/stargazers","contributors_url":"https://api.github.com/repos/diesel-rs/diesel/contributors","subscribers_url":"https://api.github.com/repos/diesel-rs/diesel/subscribers","subscription_url":"https://api.github.com/repos/diesel-rs/diesel/subscription","commits_url":"https://api.github.com/repos/diesel-rs/diesel/commits{/sha}","git_commits_url":"https://api.github.com/repos/diesel-rs/diesel/git/commits{/sha}","comments_url":"https://api.github.com/repos/diesel-rs/diesel/comments{/number}","issue_comment_url":"https://api.github.com/repos/diesel-rs/diesel/issues/comments{/number}","contents_url":"https://api.github.com/repos/diesel-rs/diesel/contents/{+path}","compare_url":"https://api.github.com/repos/diesel-rs/diesel/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diesel-rs/diesel/merges","archive_url":"https://api.github.com/repos/diesel-rs/diesel/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diesel-rs/diesel/downloads","issues_url":"https://api.github.com/repos/diesel-rs/diesel/issues{/number}","pulls_url":"https://api.github.com/repos/diesel-rs/diesel/pulls{/number}","milestones_url":"https://api.github.com/repos/diesel-rs/diesel/milestones{/number}","notifications_url":"https://api.github.com/repos/diesel-rs/diesel/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diesel-rs/diesel/labels{/name}","releases_url":"https://api.github.com/repos/diesel-rs/diesel/releases{/id}","deployments_url":"https://api.github.com/repos/diesel-rs/diesel/deployments","created_at":"2015-08-29T22:51:00Z","updated_at":"2016-04-24T18:59:23Z","pushed_at":"2016-04-24T23:46:42Z","git_url":"git://github.com/diesel-rs/diesel.git","ssh_url":"git@github.com:diesel-rs/diesel.git","clone_url":"https://github.com/diesel-rs/diesel.git","svn_url":"https://github.com/diesel-rs/diesel","homepage":"","size":4947,"stargazers_count":827,"watchers_count":827,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":49,"mirror_url":null,"open_issues_count":33,"forks":49,"open_issues":33,"watchers":827,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/303"},"html":{"href":"https://github.com/diesel-rs/diesel/pull/303"},"issue":{"href":"https://api.github.com/repos/diesel-rs/diesel/issues/303"},"comments":{"href":"https://api.github.com/repos/diesel-rs/diesel/issues/303/comments"},"review_comments":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/303/comments"},"review_comment":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/303/commits"},"statuses":{"href":"https://api.github.com/repos/diesel-rs/diesel/statuses/4e5fca99eeaec89abe59670c6b83b21c6ea064d9"}}}}