{"action":"created","comment":{"url":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments/72889912","id":72889912,"diff_hunk":"@@ -0,0 +1,151 @@\n+/// Defines a one-to-many association for the parent table. This macro is only requried if you need\n+/// to join between the two tables. This macro should be called iwth the name of the child table,\n+/// followed by any options, follwed by the entire struct body. The struct *must* be annotated with\n+/// `#[table_name(name_of_table)]`. Both the parent and child structs must implement\n+/// [`Identifiable`][identifiable].\n+///\n+/// [identifiable]: prelude/trait.Identifiable.html\n+///\n+/// # Options\n+///\n+/// ## foreign_key\n+///\n+/// Required. The name of the foreing key column for this association.\n+///\n+/// # Examples\n+///\n+/// ```no_run\n+/// # #[macro_use] extern crate diesel;\n+/// # table! { users { id -> Integer, } }\n+/// # table! { posts { id -> Integer, user_id -> Integer, } }\n+/// pub struct User {\n+///     id: i32,\n+/// }\n+/// # Identifiable! { #[table_name(users)] struct User { id: i32, } }\n+///\n+/// pub struct Post {\n+///     id: i32,\n+///     user_id: i32,\n+/// }\n+/// # Identifiable! { #[table_name(posts)] struct Post { id: i32, user_id: i32, } }\n+///\n+/// HasMany! {\n+///     (posts, foreign_key = user_id)\n+///     #[table_name(users)]\n+///     struct User {\n+///         id: i32,\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+/// [custom_derive]: https://crates.io/crates/custom_derive\n+///\n+/// ```ignore\n+/// custom_derive! {\n+///     #[derive(HasMany(posts, foreign_key = user_id)]\n+///     #[table_name(users)]\n+///     struct User {\n+///         id: i32,\n+///     }\n+/// }\n+/// ```\n+#[macro_export]\n+macro_rules! HasMany {\n+    // Format arguments\n+    (\n+        ($child_table_name:ident, foreign_key = $foreign_key_name:ident)\n+        $($rest:tt)*\n+    ) => {\n+        HasMany! {\n+            (\n+                child_table = $child_table_name::table,\n+                foreign_key = $child_table_name::$foreign_key_name,\n+            )\n+            $($rest)*\n+        }\n+    };\n+\n+    // Extract table name from struct\n+    (\n+        ($($args:tt)*)\n+        #[table_name($table_name:ident)]\n+        $($rest:tt)*\n+    ) => {\n+        HasMany! {\n+            (\n+                parent_table_name = $table_name,\n+                $($args)*\n+            )\n+            $($rest)*\n+        }\n+    };\n+\n+    // Strip meta items, pub (if present) and struct from definition\n+    (\n+        $args:tt\n+        $(#[$ignore:meta])*\n+        $(pub)* struct $($body:tt)*\n+    ) => {\n+        HasMany! {\n+            $args\n+            $($body)*\n+        }\n+    };\n+\n+    // Receive parsed fields of normal struct from `__diesel_parse_struct_body`\n+    // These patterns must appear above those which start with an ident to compile\n+    (\n+        (\n+            struct_name = $struct_name:ident,\n+            parent_table_name = $parent_table_name:ident,\n+            child_table = $child_table:path,\n+            foreign_key = $foreign_key:path,","path":"diesel/src/macros/associations/has_many.rs","position":106,"original_position":106,"commit_id":"da5ea309177a8c663a79e61a0fa6c34f67af53a2","original_commit_id":"da5ea309177a8c663a79e61a0fa6c34f67af53a2","user":{"login":"killercup","id":20063,"avatar_url":"https://avatars.githubusercontent.com/u/20063?v=3","gravatar_id":"","url":"https://api.github.com/users/killercup","html_url":"https://github.com/killercup","followers_url":"https://api.github.com/users/killercup/followers","following_url":"https://api.github.com/users/killercup/following{/other_user}","gists_url":"https://api.github.com/users/killercup/gists{/gist_id}","starred_url":"https://api.github.com/users/killercup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/killercup/subscriptions","organizations_url":"https://api.github.com/users/killercup/orgs","repos_url":"https://api.github.com/users/killercup/repos","events_url":"https://api.github.com/users/killercup/events{/privacy}","received_events_url":"https://api.github.com/users/killercup/received_events","type":"User","site_admin":false},"body":"Are these the only fields ever given here? Would it make sense/this more future-compatible if you add a generic token tree match at the end? Like `$($other_headers:tt)*`","created_at":"2016-07-30T16:08:31Z","updated_at":"2016-07-30T16:08:31Z","html_url":"https://github.com/diesel-rs/diesel/pull/386#discussion_r72889912","pull_request_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/386","_links":{"self":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/comments/72889912"},"html":{"href":"https://github.com/diesel-rs/diesel/pull/386#discussion_r72889912"},"pull_request":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/386"}}},"pull_request":{"url":"https://api.github.com/repos/diesel-rs/diesel/pulls/386","id":79457602,"html_url":"https://github.com/diesel-rs/diesel/pull/386","diff_url":"https://github.com/diesel-rs/diesel/pull/386.diff","patch_url":"https://github.com/diesel-rs/diesel/pull/386.patch","issue_url":"https://api.github.com/repos/diesel-rs/diesel/issues/386","number":386,"state":"open","locked":false,"title":"Implement `HasMany` as a stable non-procedural macro","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 follows the same approach as belongs to. I've also changed the\r\nprocedural form to more or less share code with the non-procedural, so\r\nthat we get access to `$crate`.\r\n\r\nWhen I started this process, I was really hoping to have the procedural\r\nversion just parse the options and give better error messages if they\r\nare invalid, then call the stable form. Unfortunately, because of how\r\nmacro expansion works, I can't just \"insert the struct body into the\r\nmacro call\", as at that point the struct is a single token and can't be\r\nmatched on. I'll probably end up still doing this eventually, and have\r\nthe procedural form just call the entry point that occurs after\r\n`__diesel_parse_struct_body`.","created_at":"2016-07-30T13:38:26Z","updated_at":"2016-07-30T16:08:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fb022f7acc819c63d46e3afabf89a7154b5444b7","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/386/commits","review_comments_url":"https://api.github.com/repos/diesel-rs/diesel/pulls/386/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/386/comments","statuses_url":"https://api.github.com/repos/diesel-rs/diesel/statuses/da5ea309177a8c663a79e61a0fa6c34f67af53a2","head":{"label":"diesel-rs:sg-stable-has-many","ref":"sg-stable-has-many","sha":"da5ea309177a8c663a79e61a0fa6c34f67af53a2","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-07-30T11:20:58Z","pushed_at":"2016-07-30T13:38:26Z","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":5702,"stargazers_count":994,"watchers_count":994,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":68,"mirror_url":null,"open_issues_count":61,"forks":68,"open_issues":61,"watchers":994,"default_branch":"master"}},"base":{"label":"diesel-rs:master","ref":"master","sha":"cd53276ed477aaeb6579a75f929e779076c7094a","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-07-30T11:20:58Z","pushed_at":"2016-07-30T13:38:26Z","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":5702,"stargazers_count":994,"watchers_count":994,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":68,"mirror_url":null,"open_issues_count":61,"forks":68,"open_issues":61,"watchers":994,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/386"},"html":{"href":"https://github.com/diesel-rs/diesel/pull/386"},"issue":{"href":"https://api.github.com/repos/diesel-rs/diesel/issues/386"},"comments":{"href":"https://api.github.com/repos/diesel-rs/diesel/issues/386/comments"},"review_comments":{"href":"https://api.github.com/repos/diesel-rs/diesel/pulls/386/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/386/commits"},"statuses":{"href":"https://api.github.com/repos/diesel-rs/diesel/statuses/da5ea309177a8c663a79e61a0fa6c34f67af53a2"}}}}
{"actor":{"display_login":"killercup"}}