GitHub PullRequestReviewCommentEvent at 2014-12-03 00:05:41
Repository: collect-rs
Actor: gereeter
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/Gankro/collect-rs/pulls/comments/21203271","id":21203271,"diff_hunk":"@@ -0,0 +1,1252 @@\n+use std::kinds::marker::NoCopy;\n+use std::{ptr, mem};\n+use std::iter;\n+use std::fmt::{mod, Show};\n+use std::hash::{Hash, Writer};\n+\n+/// A DList node.\n+struct Node<T> {\n+    prev: Raw<T>,\n+    next: Link<T>,\n+    elem: T,\n+}\n+\n+impl<T> Node<T> {\n+    /// Makes a node with the given element.\n+    #[inline]\n+    fn new(elem: T) -> Node<T> {\n+        Node {\n+            prev: Raw::none(),\n+            next: None,\n+            elem: elem,\n+        }\n+    }\n+\n+    /// Joins two lists.\n+    #[inline]\n+    fn link(&mut self, mut next: Box<Node<T>>) {\n+        next.prev = Raw::some(self);\n+        self.next = Some(next);\n+    }\n+\n+    /// Makes the given node come after this one, appropriately setting all other links.\n+    /// Assuming that self has a `next`.\n+    #[inline]\n+    fn splice_next(&mut self, mut next: Box<Node<T>>) {\n+        let mut old_next = self.next.take();\n+        old_next.as_mut().map(|node| node.prev = Raw::some(&mut *next));\n+        next.prev = Raw::some(self);\n+        next.next = old_next;\n+        self.next = Some(next);\n+    }\n+\n+    /// Takes the next node from this one, breaking the list into two correctly linked lists.\n+    #[inline]\n+    fn take_next(&mut self) -> Option<Box<Node<T>>> {\n+        let mut next = self.next.take();\n+        next.as_mut().map(|node| {\n+            node.prev = Raw::none();\n+        });\n+        next\n+    }\n+}\n+\n+/// An owning link.\n+type Link<T> = Option<Box<Node<T>>>;\n+\n+/// A non-owning link, based on a raw ptr.\n+struct Raw<T> {\n+    ptr: *mut Node<T>,\n+    marker: NoCopy,\n+}\n+\n+impl<T> Raw<T> {\n+    /// Makes a null reference.\n+    #[inline]\n+    fn none() -> Raw<T> {\n+        Raw { ptr: ptr::null_mut(), marker: NoCopy }\n+    }\n+\n+    /// Makes a reference to the given node.\n+    #[inline]\n+    fn some(ptr: &mut Node<T>) -> Raw<T> {\n+        Raw { ptr: ptr, marker: NoCopy }\n+    }\n+\n+    /// Converts the ref to an Option containing a reference.\n+    #[inline]\n+    fn as_ref(&self) -> Option<& Node<T>> {\n+        unsafe { self.ptr.as_ref() }\n+    }\n+\n+    /// Converts the ref to an Option containing a mutable reference.\n+    #[inline]\n+    fn as_mut(&mut self) -> Option<&mut Node<T>> {\n+        unsafe { self.ptr.as_mut() }\n+    }\n+\n+    /// Takes the reference out and nulls out this one.\n+    #[inline]\n+    fn take(&mut self) -> Raw<T> {\n+        mem::replace(self, Raw::none())\n+    }\n+\n+    /// Clones this reference. Note that mutability differs from standard clone.\n+    /// We don't want these to be cloned in the immutable case.\n+    #[inline]\n+    fn clone(&mut self) -> Raw<T> {\n+        Raw { ptr: self.ptr, marker: NoCopy }\n+    }\n+}\n+\n+/// An experimental rewrite of DList to provide a more cursor-oriented API.\n+pub struct DList<T> {\n+    len: uint,\n+    head: Link<T>,\n+    tail: Raw<T>,\n+}\n+\n+impl<T> DList<T> {\n+    /// Makes a new DList.\n+    #[inline]\n+    pub fn new() -> DList<T> {\n+        DList { head: None, tail: Raw::none(), len: 0 }\n+    }\n+\n+    /// Appends an element to the back of the list.\n+    pub fn push_back(&mut self, elem: T) {\n+        self.len += 1;\n+        let mut node = box Node::new(elem);\n+        // unconditionally make the new node the new tail\n+        let mut old_tail = mem::replace(&mut self.tail, Raw::some(&mut *node));\n+        match old_tail.as_mut() {\n+            // List was empty, so the new node is the new head\n+            None => self.head = Some(node),\n+            // List wasn't empty, just need to append this to the old tail\n+            Some(tail) => tail.link(node),\n+        }\n+\n+    }\n+\n+    /// Appends an element to the front of the list.\n+    pub fn push_front(&mut self, elem: T) {\n+        self.len += 1;\n+        let mut node = box Node::new(elem);\n+        match self.head.take() {\n+            // List was empty, so the new node is the new tail\n+            None => self.tail = Raw::some(&mut *node),\n+            // List wasn't empty, append the old head to the new node\n+            Some(head) => node.link(head),\n+        }\n+        // unconditionally make the new node the new head\n+        self.head = Some(node);\n+    }\n+\n+    /// Removes the element at back of the list. Returns None if the list is empty.\n+    pub fn pop_back(&mut self) -> Option<T> {\n+        // null out the list's tail pointer unconditionally\n+        self.tail.take().as_mut().and_then(|tail| {\n+            // tail pointer wasn't null, so decrease the len\n+            self.len -= 1;\n+            match tail.prev.take().as_mut() {\n+                // tail had no previous value, so the list only contained this node.\n+                // So we have to take this node out by removing the head itself\n+                None => self.head.take().map(|box node| node.elem),\n+                // tail had a previous value, so we need to make that the new tail\n+                // and take the node out of its next field\n+                Some(prev) => {\n+                    self.tail = Raw::some(prev);\n+                    prev.next.take().map(|box node| node.elem)\n+                }\n+            }\n+        })\n+    }\n+\n+    /// Removes the element at front of the list. Returns None if the list is empty.\n+    pub fn pop_front(&mut self) -> Option<T> {\n+        // null out the list's head pointer unconditionally\n+        self.head.take().map(|mut head| {\n+            // head wasn't null, so decrease the len\n+            self.len -= 1;\n+            match head.take_next() {\n+                // head had no next value, so just null out the tail\n+                None => self.tail = Raw::none(),\n+                // head had a next value, which should be the new head\n+                Some(next) => self.head = Some(next),\n+            }\n+            head.elem\n+        })\n+    }\n+\n+    /// Gets the element at the front of the list, or None if empty.\n+    #[inline]\n+    pub fn front(&self) -> Option<&T> {\n+        self.head.as_ref().map(|node| &node.elem)\n+    }\n+\n+    /// Gets the element at the back of the list, or None if empty.\n+    #[inline]\n+    pub fn back(&self) -> Option<&T> {\n+        self.tail.as_ref().map(|node| &node.elem)\n+    }\n+\n+    /// Gets the element at the front of the list mutably, or None if empty.\n+    #[inline]\n+    pub fn front_mut(&mut self) -> Option<&mut T> {\n+        self.head.as_mut().map(|node| &mut node.elem)\n+    }\n+\n+    /// Gets the element at the back of the list mutably, or None if empty.\n+    #[inline]\n+    pub fn back_mut(&mut self) -> Option<&mut T> {\n+        self.tail.as_mut().map(|node| &mut node.elem)\n+    }\n+\n+    /// Inserts an element at the given index.\n+    ///\n+    /// # Panics\n+    ///\n+    /// Panics if the index is greater than the length of the list.\n+    #[inline]\n+    pub fn insert(&mut self, mut index: uint, elem: T) {\n+        assert!(index <= self.len(), \"index out of bounds\");\n+        let mut cursor = self.cursor();\n+        while index > 0 { cursor.next(); index -= 1; }\n+        cursor.insert(elem);\n+    }\n+\n+    /// Removes the element at the given index. Returns None if the index is out of bounds.\n+    #[inline]\n+    pub fn remove(&mut self, mut index: uint) -> Option<T> {\n+        if index >= self.len() {\n+            None\n+        } else {\n+            let mut cursor = self.cursor();\n+            while index > 0 { cursor.next(); index -= 1; }\n+            cursor.remove()\n+        }\n+    }\n+\n+    /// Splits the list into two lists at the given index. Returns the right side of the split.\n+    /// Returns an empty list if index is out of bounds.\n+    pub fn split_at(&mut self, mut index: uint) -> DList<T> {\n+        if index >= self.len() {\n+            DList::new()\n+        } else {\n+            let mut cursor = self.cursor();\n+            while index > 0 { cursor.next(); index -= 1; }\n+            cursor.split()\n+        }\n+    }\n+\n+    /// Appends the given list to the end of this one. The old list will be empty afterwards.\n+    pub fn append(&mut self, other: &mut DList<T>) {\n+        let mut cursor = self.cursor();\n+        cursor.prev();\n+        cursor.splice(other);\n+    }\n+\n+    /// Inserts the given list at the given index. The old list will be empty afterwards.\n+    pub fn splice(&mut self, mut index: uint, other: &mut DList<T>) {\n+        let mut cursor = self.cursor();\n+        while index > 0 { cursor.next(); index -= 1; }\n+        cursor.splice(other);\n+    }\n+\n+    /// Gets the number of elements in the list.\n+    #[inline]\n+    pub fn len(&self) -> uint {\n+        self.len\n+    }\n+\n+    /// Whether the list is empty.\n+    #[inline]\n+    pub fn is_empty(&self) -> bool {\n+        self.len == 0\n+    }\n+\n+    /// Removes all elements from the list.\n+    #[inline]\n+    pub fn clear(&mut self) {\n+        while !self.is_empty() {\n+            self.pop_front();\n+        }\n+    }\n+\n+    /// Gets a cursor over the list.\n+    #[inline]\n+    pub fn cursor(&mut self) -> Cursor<T> {\n+        Cursor {\n+            list: self,\n+            prev: Raw::none(),\n+            index: 0,\n+        }\n+    }\n+\n+    /// Provides a forward iterator.\n+    #[inline]\n+    pub fn iter<'a>(&'a self) -> Items<'a, T> {\n+        Items{nelem: self.len(), head: &self.head, tail: &self.tail}\n+    }\n+\n+    /// Provides a forward iterator with mutable references.\n+    #[inline]\n+    pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {\n+        let head_raw = match self.head.as_mut() {\n+            Some(head) => Raw::some(&mut **head),\n+            None => Raw::none(),\n+        };\n+        MutItems{\n+            nelem: self.len(),\n+            head: head_raw,\n+            tail: self.tail.clone(),\n+        }\n+    }\n+\n+    /// Consumes the list into an iterator yielding elements by.elem.\n+    #[inline]\n+    pub fn into_iter(self) -> MoveItems<T> {\n+        MoveItems{list: self}\n+    }\n+\n+}\n+\n+/// A Cursor is like an iterator, except that it can freely seek back-and-forth, and can\n+/// safely mutate the list during iteration. This is because the lifetime of its yielded\n+/// references are tied to its own lifetime, instead of just the underlying list. This means\n+/// cursors cannot yield multiple elements at once.\n+///\n+/// Cursors always rest between two elements in the list, and index in a logically circular way.\n+/// To accomadate this, there is a \"ghost\" non-element that yields None between the head and tail\n+/// of the List.\n+///\n+/// When created, cursors start between the ghost and the front of the list. That is, `next` will\n+/// yield the front of the list, and `prev` will yield None. Calling `prev` again will yield\n+/// the tail.\n+pub struct Cursor<'a, T: 'a> {\n+    list: &'a mut DList<T>,","path":"src/proto/dlist.rs","position":327,"original_position":327,"commit_id":"5d82c8a2c6bf827a3ec6ee80d5080a25e3e59de4","original_commit_id":"5d82c8a2c6bf827a3ec6ee80d5080a25e3e59de4","user":{"login":"gereeter","id":2328242,"avatar_url":"https://avatars.githubusercontent.com/u/2328242?v=3","gravatar_id":"","url":"https://api.github.com/users/gereeter","html_url":"https://github.com/gereeter","followers_url":"https://api.github.com/users/gereeter/followers","following_url":"https://api.github.com/users/gereeter/following{/other_user}","gists_url":"https://api.github.com/users/gereeter/gists{/gist_id}","starred_url":"https://api.github.com/users/gereeter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gereeter/subscriptions","organizations_url":"https://api.github.com/users/gereeter/orgs","repos_url":"https://api.github.com/users/gereeter/repos","events_url":"https://api.github.com/users/gereeter/events{/privacy}","received_events_url":"https://api.github.com/users/gereeter/received_events","type":"User","site_admin":false},"body":"Unfortunately, I think that using `&mut` here is unsound. As I understand it, writes to `&mut` pointers cannot be observed except from anywhere except through themselves, and similary, reads from `&mut` pointers cannot be influenced by writes not through that pointer.\r\n\r\nHowever, the cursor switches between using `list` and `prev`, thereby leaking writes from one to the other, which is illegal. An example of how LLVM might misoptimize this:\r\n\r\n```rust\r\nlet mut cursor = list.cursor_back();\r\ncursor.insert(5);\r\nassert!(cursor.next().is_none());\r\n```\r\n\r\nWith the cursor at the end of the list, `insert()` delegates to `list.push_back()`. Since this is through a `noalias` pointer, it cannot (as far as LLVM knows) affect reads to `prev`. Therefore, it might notice that in the `insert` method, `prev` was found to point at the end of the list, so the same check in `next()` can be optimized away to saying that we are at the end of the list.","created_at":"2014-12-03T00:05:41Z","updated_at":"2014-12-03T00:05:41Z","html_url":"https://github.com/Gankro/collect-rs/pull/11#discussion_r21203271","pull_request_url":"https://api.github.com/repos/Gankro/collect-rs/pulls/11","_links":{"self":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/comments/21203271"},"html":{"href":"https://github.com/Gankro/collect-rs/pull/11#discussion_r21203271"},"pull_request":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/11"}}},"pull_request":{"url":"https://api.github.com/repos/Gankro/collect-rs/pulls/11","id":25229263,"html_url":"https://github.com/Gankro/collect-rs/pull/11","diff_url":"https://github.com/Gankro/collect-rs/pull/11.diff","patch_url":"https://github.com/Gankro/collect-rs/pull/11.patch","issue_url":"https://api.github.com/repos/Gankro/collect-rs/issues/11","number":11,"state":"open","locked":false,"title":"Prototype Dlist rewrite with cursor","user":{"login":"Gankro","id":1136864,"avatar_url":"https://avatars.githubusercontent.com/u/1136864?v=3","gravatar_id":"","url":"https://api.github.com/users/Gankro","html_url":"https://github.com/Gankro","followers_url":"https://api.github.com/users/Gankro/followers","following_url":"https://api.github.com/users/Gankro/following{/other_user}","gists_url":"https://api.github.com/users/Gankro/gists{/gist_id}","starred_url":"https://api.github.com/users/Gankro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gankro/subscriptions","organizations_url":"https://api.github.com/users/Gankro/orgs","repos_url":"https://api.github.com/users/Gankro/repos","events_url":"https://api.github.com/users/Gankro/events{/privacy}","received_events_url":"https://api.github.com/users/Gankro/received_events","type":"User","site_admin":false},"body":"","created_at":"2014-11-30T00:45:51Z","updated_at":"2014-12-03T00:05:41Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a77fc032088158d4459051ec46d6c5e19a41e82d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Gankro/collect-rs/pulls/11/commits","review_comments_url":"https://api.github.com/repos/Gankro/collect-rs/pulls/11/comments","review_comment_url":"https://api.github.com/repos/Gankro/collect-rs/pulls/comments/{number}","comments_url":"https://api.github.com/repos/Gankro/collect-rs/issues/11/comments","statuses_url":"https://api.github.com/repos/Gankro/collect-rs/statuses/5d82c8a2c6bf827a3ec6ee80d5080a25e3e59de4","head":{"label":"Gankro:dlist","ref":"dlist","sha":"5d82c8a2c6bf827a3ec6ee80d5080a25e3e59de4","user":{"login":"Gankro","id":1136864,"avatar_url":"https://avatars.githubusercontent.com/u/1136864?v=3","gravatar_id":"","url":"https://api.github.com/users/Gankro","html_url":"https://github.com/Gankro","followers_url":"https://api.github.com/users/Gankro/followers","following_url":"https://api.github.com/users/Gankro/following{/other_user}","gists_url":"https://api.github.com/users/Gankro/gists{/gist_id}","starred_url":"https://api.github.com/users/Gankro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gankro/subscriptions","organizations_url":"https://api.github.com/users/Gankro/orgs","repos_url":"https://api.github.com/users/Gankro/repos","events_url":"https://api.github.com/users/Gankro/events{/privacy}","received_events_url":"https://api.github.com/users/Gankro/received_events","type":"User","site_admin":false},"repo":{"id":25849693,"name":"collect-rs","full_name":"Gankro/collect-rs","owner":{"login":"Gankro","id":1136864,"avatar_url":"https://avatars.githubusercontent.com/u/1136864?v=3","gravatar_id":"","url":"https://api.github.com/users/Gankro","html_url":"https://github.com/Gankro","followers_url":"https://api.github.com/users/Gankro/followers","following_url":"https://api.github.com/users/Gankro/following{/other_user}","gists_url":"https://api.github.com/users/Gankro/gists{/gist_id}","starred_url":"https://api.github.com/users/Gankro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gankro/subscriptions","organizations_url":"https://api.github.com/users/Gankro/orgs","repos_url":"https://api.github.com/users/Gankro/repos","events_url":"https://api.github.com/users/Gankro/events{/privacy}","received_events_url":"https://api.github.com/users/Gankro/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Gankro/collect-rs","description":"Miscellaneous Collections","fork":false,"url":"https://api.github.com/repos/Gankro/collect-rs","forks_url":"https://api.github.com/repos/Gankro/collect-rs/forks","keys_url":"https://api.github.com/repos/Gankro/collect-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Gankro/collect-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Gankro/collect-rs/teams","hooks_url":"https://api.github.com/repos/Gankro/collect-rs/hooks","issue_events_url":"https://api.github.com/repos/Gankro/collect-rs/issues/events{/number}","events_url":"https://api.github.com/repos/Gankro/collect-rs/events","assignees_url":"https://api.github.com/repos/Gankro/collect-rs/assignees{/user}","branches_url":"https://api.github.com/repos/Gankro/collect-rs/branches{/branch}","tags_url":"https://api.github.com/repos/Gankro/collect-rs/tags","blobs_url":"https://api.github.com/repos/Gankro/collect-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Gankro/collect-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Gankro/collect-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/Gankro/collect-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Gankro/collect-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/Gankro/collect-rs/languages","stargazers_url":"https://api.github.com/repos/Gankro/collect-rs/stargazers","contributors_url":"https://api.github.com/repos/Gankro/collect-rs/contributors","subscribers_url":"https://api.github.com/repos/Gankro/collect-rs/subscribers","subscription_url":"https://api.github.com/repos/Gankro/collect-rs/subscription","commits_url":"https://api.github.com/repos/Gankro/collect-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/Gankro/collect-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/Gankro/collect-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/Gankro/collect-rs/issues/comments/{number}","contents_url":"https://api.github.com/repos/Gankro/collect-rs/contents/{+path}","compare_url":"https://api.github.com/repos/Gankro/collect-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Gankro/collect-rs/merges","archive_url":"https://api.github.com/repos/Gankro/collect-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Gankro/collect-rs/downloads","issues_url":"https://api.github.com/repos/Gankro/collect-rs/issues{/number}","pulls_url":"https://api.github.com/repos/Gankro/collect-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/Gankro/collect-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/Gankro/collect-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Gankro/collect-rs/labels{/name}","releases_url":"https://api.github.com/repos/Gankro/collect-rs/releases{/id}","created_at":"2014-10-28T02:35:00Z","updated_at":"2014-12-01T11:40:54Z","pushed_at":"2014-11-30T21:47:14Z","git_url":"git://github.com/Gankro/collect-rs.git","ssh_url":"git@github.com:Gankro/collect-rs.git","clone_url":"https://github.com/Gankro/collect-rs.git","svn_url":"https://github.com/Gankro/collect-rs","homepage":"","size":317,"stargazers_count":20,"watchers_count":20,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":9,"forks":7,"open_issues":9,"watchers":20,"default_branch":"master"}},"base":{"label":"Gankro:master","ref":"master","sha":"42f88b7fa4872cbe179e57b44e969a3d1a2f6248","user":{"login":"Gankro","id":1136864,"avatar_url":"https://avatars.githubusercontent.com/u/1136864?v=3","gravatar_id":"","url":"https://api.github.com/users/Gankro","html_url":"https://github.com/Gankro","followers_url":"https://api.github.com/users/Gankro/followers","following_url":"https://api.github.com/users/Gankro/following{/other_user}","gists_url":"https://api.github.com/users/Gankro/gists{/gist_id}","starred_url":"https://api.github.com/users/Gankro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gankro/subscriptions","organizations_url":"https://api.github.com/users/Gankro/orgs","repos_url":"https://api.github.com/users/Gankro/repos","events_url":"https://api.github.com/users/Gankro/events{/privacy}","received_events_url":"https://api.github.com/users/Gankro/received_events","type":"User","site_admin":false},"repo":{"id":25849693,"name":"collect-rs","full_name":"Gankro/collect-rs","owner":{"login":"Gankro","id":1136864,"avatar_url":"https://avatars.githubusercontent.com/u/1136864?v=3","gravatar_id":"","url":"https://api.github.com/users/Gankro","html_url":"https://github.com/Gankro","followers_url":"https://api.github.com/users/Gankro/followers","following_url":"https://api.github.com/users/Gankro/following{/other_user}","gists_url":"https://api.github.com/users/Gankro/gists{/gist_id}","starred_url":"https://api.github.com/users/Gankro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gankro/subscriptions","organizations_url":"https://api.github.com/users/Gankro/orgs","repos_url":"https://api.github.com/users/Gankro/repos","events_url":"https://api.github.com/users/Gankro/events{/privacy}","received_events_url":"https://api.github.com/users/Gankro/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Gankro/collect-rs","description":"Miscellaneous Collections","fork":false,"url":"https://api.github.com/repos/Gankro/collect-rs","forks_url":"https://api.github.com/repos/Gankro/collect-rs/forks","keys_url":"https://api.github.com/repos/Gankro/collect-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Gankro/collect-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Gankro/collect-rs/teams","hooks_url":"https://api.github.com/repos/Gankro/collect-rs/hooks","issue_events_url":"https://api.github.com/repos/Gankro/collect-rs/issues/events{/number}","events_url":"https://api.github.com/repos/Gankro/collect-rs/events","assignees_url":"https://api.github.com/repos/Gankro/collect-rs/assignees{/user}","branches_url":"https://api.github.com/repos/Gankro/collect-rs/branches{/branch}","tags_url":"https://api.github.com/repos/Gankro/collect-rs/tags","blobs_url":"https://api.github.com/repos/Gankro/collect-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Gankro/collect-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Gankro/collect-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/Gankro/collect-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Gankro/collect-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/Gankro/collect-rs/languages","stargazers_url":"https://api.github.com/repos/Gankro/collect-rs/stargazers","contributors_url":"https://api.github.com/repos/Gankro/collect-rs/contributors","subscribers_url":"https://api.github.com/repos/Gankro/collect-rs/subscribers","subscription_url":"https://api.github.com/repos/Gankro/collect-rs/subscription","commits_url":"https://api.github.com/repos/Gankro/collect-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/Gankro/collect-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/Gankro/collect-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/Gankro/collect-rs/issues/comments/{number}","contents_url":"https://api.github.com/repos/Gankro/collect-rs/contents/{+path}","compare_url":"https://api.github.com/repos/Gankro/collect-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Gankro/collect-rs/merges","archive_url":"https://api.github.com/repos/Gankro/collect-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Gankro/collect-rs/downloads","issues_url":"https://api.github.com/repos/Gankro/collect-rs/issues{/number}","pulls_url":"https://api.github.com/repos/Gankro/collect-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/Gankro/collect-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/Gankro/collect-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Gankro/collect-rs/labels{/name}","releases_url":"https://api.github.com/repos/Gankro/collect-rs/releases{/id}","created_at":"2014-10-28T02:35:00Z","updated_at":"2014-12-01T11:40:54Z","pushed_at":"2014-11-30T21:47:14Z","git_url":"git://github.com/Gankro/collect-rs.git","ssh_url":"git@github.com:Gankro/collect-rs.git","clone_url":"https://github.com/Gankro/collect-rs.git","svn_url":"https://github.com/Gankro/collect-rs","homepage":"","size":317,"stargazers_count":20,"watchers_count":20,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":9,"forks":7,"open_issues":9,"watchers":20,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/11"},"html":{"href":"https://github.com/Gankro/collect-rs/pull/11"},"issue":{"href":"https://api.github.com/repos/Gankro/collect-rs/issues/11"},"comments":{"href":"https://api.github.com/repos/Gankro/collect-rs/issues/11/comments"},"review_comments":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/11/comments"},"review_comment":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/Gankro/collect-rs/pulls/11/commits"},"statuses":{"href":"https://api.github.com/repos/Gankro/collect-rs/statuses/5d82c8a2c6bf827a3ec6ee80d5080a25e3e59de4"}}}}