{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/25747","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/25747/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/25747/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/25747/events","html_url":"https://github.com/rust-lang/rust/pull/25747","id":80135318,"number":25747,"title":"Add std::cell::map_ref","user":{"login":"SimonSapin","id":291359,"avatar_url":"https://avatars.githubusercontent.com/u/291359?v=3","gravatar_id":"","url":"https://api.github.com/users/SimonSapin","html_url":"https://github.com/SimonSapin","followers_url":"https://api.github.com/users/SimonSapin/followers","following_url":"https://api.github.com/users/SimonSapin/following{/other_user}","gists_url":"https://api.github.com/users/SimonSapin/gists{/gist_id}","starred_url":"https://api.github.com/users/SimonSapin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SimonSapin/subscriptions","organizations_url":"https://api.github.com/users/SimonSapin/orgs","repos_url":"https://api.github.com/users/SimonSapin/repos","events_url":"https://api.github.com/users/SimonSapin/events{/privacy}","received_events_url":"https://api.github.com/users/SimonSapin/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/T-libs","name":"T-libs","color":"bfd4f2"}],"state":"open","locked":false,"assignee":{"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},"milestone":null,"comments":30,"created_at":"2015-05-24T11:35:43Z","updated_at":"2015-05-27T16:22:48Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/25747","html_url":"https://github.com/rust-lang/rust/pull/25747","diff_url":"https://github.com/rust-lang/rust/pull/25747.diff","patch_url":"https://github.com/rust-lang/rust/pull/25747.patch"},"body":"For slightly complex data structures like `rustc_serialize::json::Json`, it is often convenient to have helper methods like `Json::as_string(&self) -> Option<&str>`  that return a borrow of some component of `&self`.\r\n\r\nHowever, when `RefCell`s are involved, keeping a `Ref` around is required to hold a borrow to the insides of a `RefCell`. But `Ref` so far only references the entirety of the contents of a `RefCell`, not a component. But there is no reason it couldn’t: `Ref` internally contains just a data reference and a borrow count reference. The two can be dissociated.\r\n\r\nThis adds a `map_ref` function that creates a new `Ref` for some other data, but borrowing the same `RefCell` as an existing `Ref`.\r\n\r\nExample:\r\n\r\n```rust\r\nstruct RefCellJson(RefCell<Json>);\r\n\r\nimpl RefCellJson {\r\n    fn as_string(&self) -> Option<Ref<str>> {\r\n        make_ref(self.borrow(), |j| j.as_string())\r\n    }\r\n}\r\n```\r\n\r\nr? @alexcrichton "},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/105983964","html_url":"https://github.com/rust-lang/rust/pull/25747#issuecomment-105983964","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/25747","id":105983964,"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},"created_at":"2015-05-27T16:22:48Z","updated_at":"2015-05-27T16:22:48Z","body":"This API looks good to me, and I also believe the implementation is sound, so I'm all good with this!\r\n\r\nI'd like to hear more opinions about `Type::foo` as opposed to `std::type::foo` as well as how fancy we want to get with the extra methods on `Ref{,Mut}`."}}