{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/23434087","id":23434087,"diff_hunk":"@@ -473,12 +635,289 @@ throughout IO, we can go on to explore the modules in detail.\n ### `core::io`\n [core::io]: #coreio\n \n-> To be added in a follow-up PR.\n+The `io` module is split into the parts that can live in `libcore`\n+(most of it) and the parts that are added in the `std::io`\n+facade. Being able to move components into `libcore` at all is made\n+possible through the use of\n+[associated error types](#revising-reader-and-writer) for `Reader` and\n+`Writer`.\n+\n+#### Adapters\n+[Adapters]: #adapters\n+\n+The current `std::io::util` module offers a number of `Reader` and\n+`Writer` \"adapters\". This RFC refactors the design to more closely\n+follow `std::iter`. Along the way, it generalizes the `by_ref` adapter:\n+\n+```rust\n+trait ReadExt: Read {\n+    // ... eliding the methods already described above\n+\n+    // Reify a borrowed reader as owned\n+    fn by_ref<'a>(&'a mut self) -> ByRef<'a, Self> { ... }\n+\n+    // Read everything from `self`, then read from `next`\n+    fn chain<R: Reader>(self, next: R) -> Chain<Self, R> { ... }\n+\n+    // Adapt `self` to yield only the first `limit` bytes\n+    fn take(self, limit: u64) -> Take<Self> { ... }\n+\n+    // Whenever reading from `self`, push the bytes read to `out`\n+    fn tee<W: Writer>(self, out: W) -> Tee<Self, W> { ... }\n+}\n+\n+trait WriteExt: Write {\n+    // ... eliding the methods already described above\n+\n+    // Reify a borrowed writer as owned\n+    fn by_ref<'a>(&'a mut self) -> ByRef<'a, Self> { ... }\n+\n+    // Whenever bytes are written to `self`, write them to `other` as well\n+    fn broadcast<W: Writer>(self, other: W) -> Broadcast<Self, W> { ... }\n+}\n+\n+// An adaptor converting an `Iterator<u8>` to `Read`.\n+pub struct IterReader<T> { ... }\n+```\n+\n+As with `std::iter`, these adapters are object unsafe and hence placed\n+in an extension trait with a blanket `impl`.\n+\n+Note that the same `ByRef` type is used for both `Read` and `Write`\n+-- and this RFC proposes to use it for `std::iter` as well. The\n+insight is that there is no difference between the *type* used for\n+by-ref adapters in any of these cases; what changes is just which\n+trait defers through it. So, we propose to add the following to `core::borrow`:\n+\n+```rust\n+pub struct ByRef<'a, Sized? T:'a> {\n+    pub inner: &'a mut T\n+}\n+```\n+\n+which will allow `impl`s like the following in `core::io`:\n+\n+```rust\n+impl<'a, W: Write> Write for ByRef<'a, W> {\n+    #[inline]\n+    fn write(&mut self, buf: &[u8]) -> Result<uint, W::Err> { self.inner.write(buf) }\n+\n+    #[inline]\n+    fn flush(&mut self) -> Result<(), W::Err> { self.inner.flush() }\n+}\n+```\n+\n+#### Free functions\n+[Free functions]: #free-functions\n+\n+The current `std::io::util` module also includes a number of primitive\n+readers and writers, as well as `copy`. These are updated as follows:\n+\n+```rust\n+// A reader that yields no bytes\n+fn empty() -> Empty; // in theory just returns `impl Reader`\n+\n+// A reader that yields `byte` repeatedly (generalizes today's ZeroReader)\n+fn repeat(byte: u8) -> Repeat;\n+\n+// A writer that ignores the bytes written to it (/dev/null)\n+fn sink() -> Sink;","path":"text/0517-io-os-reform.md","position":279,"original_position":279,"commit_id":"95b42dbff0e9240538b690c7efd930aea9712b0a","original_commit_id":"95b42dbff0e9240538b690c7efd930aea9712b0a","user":{"login":"alexcrichton","id":64996,"avatar_url":"https://avatars.githubusercontent.com/u/64996?v=3","gravatar_id":"","url":"https://api.github.com/users/alexcrichton","html_url":"https://github.com/alexcrichton","followers_url":"https://api.github.com/users/alexcrichton/followers","following_url":"https://api.github.com/users/alexcrichton/following{/other_user}","gists_url":"https://api.github.com/users/alexcrichton/gists{/gist_id}","starred_url":"https://api.github.com/users/alexcrichton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexcrichton/subscriptions","organizations_url":"https://api.github.com/users/alexcrichton/orgs","repos_url":"https://api.github.com/users/alexcrichton/repos","events_url":"https://api.github.com/users/alexcrichton/events{/privacy}","received_events_url":"https://api.github.com/users/alexcrichton/received_events","type":"User","site_admin":false},"body":"Hm, this seems to be a general question for a good number of adaptors and such. For example all the implementations on `Cursor` need an error type but they never actually need to create it.","created_at":"2015-01-23T06:37:04Z","updated_at":"2015-01-23T06:37:04Z","html_url":"https://github.com/rust-lang/rfcs/pull/576#discussion_r23434087","pull_request_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/576","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/23434087"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/576#discussion_r23434087"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/576"}}},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/576","id":27239618,"html_url":"https://github.com/rust-lang/rfcs/pull/576","diff_url":"https://github.com/rust-lang/rfcs/pull/576.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/576.patch","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/576","number":576,"state":"open","locked":false,"title":"Amend RFC 517: Revisions to reader/writer, core::io and std::io","user":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"body":"The [IO reform RFC](https://github.com/rust-lang/rfcs/pull/517) is [being split](https://github.com/rust-lang/rfcs/pull/517#issuecomment-69669731) into several semi-independent pieces, posted as PRs like this one.\r\n\r\nThis RFC amendment adds the sections on `Reader`/`Writer` revisions, as well as `core::io` and `std::io` (which are closely related).\r\n\r\n[Rendered](https://github.com/aturon/rfcs/blob/io-reader-writer/text/0517-io-os-reform.md)","created_at":"2015-01-13T00:41:17Z","updated_at":"2015-01-23T06:37:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b014ebbfbf6bdb29f79359072e5fc0e26cf0ffcd","assignee":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/576/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/576/comments","review_comment_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/{number}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/576/comments","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/95b42dbff0e9240538b690c7efd930aea9712b0a","head":{"label":"aturon:io-reader-writer","ref":"io-reader-writer","sha":"95b42dbff0e9240538b690c7efd930aea9712b0a","user":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"repo":{"id":20423396,"name":"rfcs","full_name":"aturon/rfcs","owner":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/aturon/rfcs","description":"RFCs for changes to Rust","fork":true,"url":"https://api.github.com/repos/aturon/rfcs","forks_url":"https://api.github.com/repos/aturon/rfcs/forks","keys_url":"https://api.github.com/repos/aturon/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aturon/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aturon/rfcs/teams","hooks_url":"https://api.github.com/repos/aturon/rfcs/hooks","issue_events_url":"https://api.github.com/repos/aturon/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/aturon/rfcs/events","assignees_url":"https://api.github.com/repos/aturon/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/aturon/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/aturon/rfcs/tags","blobs_url":"https://api.github.com/repos/aturon/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aturon/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aturon/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/aturon/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aturon/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/aturon/rfcs/languages","stargazers_url":"https://api.github.com/repos/aturon/rfcs/stargazers","contributors_url":"https://api.github.com/repos/aturon/rfcs/contributors","subscribers_url":"https://api.github.com/repos/aturon/rfcs/subscribers","subscription_url":"https://api.github.com/repos/aturon/rfcs/subscription","commits_url":"https://api.github.com/repos/aturon/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/aturon/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/aturon/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/aturon/rfcs/issues/comments/{number}","contents_url":"https://api.github.com/repos/aturon/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/aturon/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aturon/rfcs/merges","archive_url":"https://api.github.com/repos/aturon/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aturon/rfcs/downloads","issues_url":"https://api.github.com/repos/aturon/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/aturon/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/aturon/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/aturon/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aturon/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/aturon/rfcs/releases{/id}","created_at":"2014-06-02T23:35:56Z","updated_at":"2015-01-17T17:42:40Z","pushed_at":"2015-01-23T03:15:44Z","git_url":"git://github.com/aturon/rfcs.git","ssh_url":"git@github.com:aturon/rfcs.git","clone_url":"https://github.com/aturon/rfcs.git","svn_url":"https://github.com/aturon/rfcs","homepage":"","size":2060,"stargazers_count":4,"watchers_count":4,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":4,"default_branch":"master"}},"base":{"label":"rust-lang:master","ref":"master","sha":"e0999be5aade97bb794d9f886bac31cfcb0f8a8d","user":{"login":"rust-lang","id":5430905,"avatar_url":"https://avatars.githubusercontent.com/u/5430905?v=3","gravatar_id":"","url":"https://api.github.com/users/rust-lang","html_url":"https://github.com/rust-lang","followers_url":"https://api.github.com/users/rust-lang/followers","following_url":"https://api.github.com/users/rust-lang/following{/other_user}","gists_url":"https://api.github.com/users/rust-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-lang/subscriptions","organizations_url":"https://api.github.com/users/rust-lang/orgs","repos_url":"https://api.github.com/users/rust-lang/repos","events_url":"https://api.github.com/users/rust-lang/events{/privacy}","received_events_url":"https://api.github.com/users/rust-lang/received_events","type":"Organization","site_admin":false},"repo":{"id":17527989,"name":"rfcs","full_name":"rust-lang/rfcs","owner":{"login":"rust-lang","id":5430905,"avatar_url":"https://avatars.githubusercontent.com/u/5430905?v=3","gravatar_id":"","url":"https://api.github.com/users/rust-lang","html_url":"https://github.com/rust-lang","followers_url":"https://api.github.com/users/rust-lang/followers","following_url":"https://api.github.com/users/rust-lang/following{/other_user}","gists_url":"https://api.github.com/users/rust-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-lang/subscriptions","organizations_url":"https://api.github.com/users/rust-lang/orgs","repos_url":"https://api.github.com/users/rust-lang/repos","events_url":"https://api.github.com/users/rust-lang/events{/privacy}","received_events_url":"https://api.github.com/users/rust-lang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rust-lang/rfcs","description":"RFCs for changes to Rust","fork":false,"url":"https://api.github.com/repos/rust-lang/rfcs","forks_url":"https://api.github.com/repos/rust-lang/rfcs/forks","keys_url":"https://api.github.com/repos/rust-lang/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rust-lang/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rust-lang/rfcs/teams","hooks_url":"https://api.github.com/repos/rust-lang/rfcs/hooks","issue_events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/rust-lang/rfcs/events","assignees_url":"https://api.github.com/repos/rust-lang/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/rust-lang/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/rust-lang/rfcs/tags","blobs_url":"https://api.github.com/repos/rust-lang/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rust-lang/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rust-lang/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/rust-lang/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/rust-lang/rfcs/languages","stargazers_url":"https://api.github.com/repos/rust-lang/rfcs/stargazers","contributors_url":"https://api.github.com/repos/rust-lang/rfcs/contributors","subscribers_url":"https://api.github.com/repos/rust-lang/rfcs/subscribers","subscription_url":"https://api.github.com/repos/rust-lang/rfcs/subscription","commits_url":"https://api.github.com/repos/rust-lang/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/rust-lang/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments/{number}","contents_url":"https://api.github.com/repos/rust-lang/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/rust-lang/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rust-lang/rfcs/merges","archive_url":"https://api.github.com/repos/rust-lang/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rust-lang/rfcs/downloads","issues_url":"https://api.github.com/repos/rust-lang/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/rust-lang/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/rust-lang/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/rust-lang/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rust-lang/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/rust-lang/rfcs/releases{/id}","created_at":"2014-03-07T21:29:00Z","updated_at":"2015-01-22T20:11:25Z","pushed_at":"2015-01-23T04:12:19Z","git_url":"git://github.com/rust-lang/rfcs.git","ssh_url":"git@github.com:rust-lang/rfcs.git","clone_url":"https://github.com/rust-lang/rfcs.git","svn_url":"https://github.com/rust-lang/rfcs","homepage":"","size":7144,"stargazers_count":241,"watchers_count":241,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":149,"mirror_url":null,"open_issues_count":335,"forks":149,"open_issues":335,"watchers":241,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/576"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/576"},"issue":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/576"},"comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/576/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/576/comments"},"review_comment":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/576/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rfcs/statuses/95b42dbff0e9240538b690c7efd930aea9712b0a"}}}}