{"id":18016901,"url":"https://github.com/fitzgen/rent_to_own","last_synced_at":"2025-03-26T18:32:31.999Z","repository":{"id":57660041,"uuid":"112538967","full_name":"fitzgen/rent_to_own","owner":"fitzgen","description":"A wrapper type for optionally giving up ownership of the underlying value.","archived":false,"fork":false,"pushed_at":"2018-03-06T17:38:34.000Z","size":11,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-17T11:59:44.307Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fitzgen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-29T23:17:26.000Z","updated_at":"2024-08-28T22:51:13.000Z","dependencies_parsed_at":"2022-09-26T20:31:08.978Z","dependency_job_id":null,"html_url":"https://github.com/fitzgen/rent_to_own","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitzgen%2Frent_to_own","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitzgen%2Frent_to_own/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitzgen%2Frent_to_own/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitzgen%2Frent_to_own/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fitzgen","download_url":"https://codeload.github.com/fitzgen/rent_to_own/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245713145,"owners_count":20660352,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-30T04:19:38.637Z","updated_at":"2025-03-26T18:32:31.719Z","avatar_url":"https://github.com/fitzgen.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rent_to_own\n\n[![](https://docs.rs/rent_to_own/badge.svg)](https://docs.rs/rent_to_own/) [![](https://img.shields.io/crates/v/rent_to_own.svg)](https://crates.io/crates/rent_to_own) [![](https://img.shields.io/crates/d/rent_to_own.png)](https://crates.io/crates/rent_to_own) [![Build Status](https://travis-ci.org/fitzgen/rent_to_own.png?branch=master)](https://travis-ci.org/fitzgen/rent_to_own)\n\n`RentToOwn\u003cT\u003e`: A wrapper type for optionally giving up ownership of the\nunderlying value.\n\n`RentToOwn\u003cT\u003e` is useful in situations where\n\n1. a function might want to *conditionally take ownership* of some `T`\nvalue, and\n\n2. that function cannot take the `T` by value and return an `Option\u003cT\u003e` to maybe\ngive the `T` value back if it doesn't want ownership.\n\n`RentToOwn\u003cT\u003e` dereferences (immutably and mutably) to its inner `T` value, and\nadditionally provides a `take` method that gives up ownership of the inner value\nto the caller.\n\nUnder the covers, `RentToOwn\u003cT\u003e` is essentially an `Option\u003cT\u003e` that gets\nunwrapped when dereferenced and calls `Option::take` if we need to take\nownership of the inner value. The key advantage over using `Option\u003cT\u003e` directly,\nother than the `Deref` sugar, is some lifetime trickery to statically prevent\nall unwrapping panics that would arise from using the `RentToOwn\u003cT\u003e` wrapper\nagain after the inner value has been taken. Once the inner value is taken, the\nborrow checker will ensure that the original `RentToOwn\u003cT\u003e` cannot be used\nanymore. See the `take` method's documentation for details.\n\n### Example\n\nIn this example, if the `configure` function encounters any errors, we do not\nwish to drop the `BigExpensiveResource`, but instead allow the caller to handle\nthe error and then reuse the resource. In effect, the `configure` function is\nconditionally taking ownership of the `BigExpensiveResource` depending on if\nthere are IO errors or not.\n\n```rust\nuse rent_to_own::RentToOwn;\n\nuse std::io::{self, Read};\nuse std::fs;\n\n/// This is a big, expensive to create (or maybe even unique) resource, and we\n/// want to reuse it even if `configure` returns an error.\nstruct BigExpensiveResource {\n    // ...\n}\n\n#[derive(Default)]\nstruct Config {\n    // ...\n}\n\n/// A big, expensive resource that has been properly configured.\nstruct ConfiguredResource {\n    resource: BigExpensiveResource,\n    config: Config,\n}\n\nfn read_and_parse_config_file() -\u003e io::Result\u003cConfig\u003e {\n    // ...\n}\n\nfn configure\u003c'a\u003e(\n    resource: \u0026'a mut RentToOwn\u003c'a, BigExpensiveResource\u003e\n) -\u003e io::Result\u003cConfiguredResource\u003e {\n    // We use normal error propagation with `?`. Because we haven't `take`n the\n    // resource out of the `RentToOwn`, if we early return here the caller still\n    // controls the `BigExpensiveResource` and it isn't dropped.\n    let config = read_and_parse_config_file()?;\n\n    // Now we `take` ownership of the resource and return the configured\n    // resource.\n    let resource = resource.take();\n    Ok(ConfiguredResource { resource, config })\n}\n```\n\nWhat does `configure`'s caller look like? It calls `RentToOwn::with` to\nconstruct the `RentToOwn\u003cBigExpensiveResource\u003e` and invoke a closure with\nit. Then it inspects the results of the closure and whether the\n`BigExpensiveResource` was taken or not.\n\nIn this example, the caller can recover from any IO error when reading or\nparsing the configuration file and use a default configuration with the\n`BigExpensiveResource` instead.\n\n```rust\nfn use_custom_configuration_or_default(resource: BigExpensiveResource) -\u003e ConfiguredResource {\n    // We pass the resource into `with` and it constructs the `RentToOwn`\n    // wrapper around it and then gives the wrapper to the closure. Finally, it\n    // returns a pair of an `Option\u003cBigExpensiveResource\u003e` which is `None` if\n    // the closure took ownership and `Some` if it did not, and the closure's\n    // return value.\n    let (resource, result) = RentToOwn::with(resource, |resource| {\n        configure(resource)\n    });\n\n    if let Ok(configured) = result {\n        return configured;\n    }\n\n    // Reuse the resource if the closure did not take ownership or else\n    // reconstruct it if the closure did take ownership. (In this particular\n    // example, we know that `configure` took ownership if and only if the\n    // result was `Ok`, but that doesn't hold for all possible examples.)\n    // Finally, return the configured resource with the default configuration.\n    let resource = resource.unwrap_or_else(|| BigExpensiveResource::reconstruct());\n    let config = Config::default();\n    ConfiguredResource { resource, config }\n}\n```\n\n\nLicense: Apache-2.0/MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffitzgen%2Frent_to_own","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffitzgen%2Frent_to_own","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffitzgen%2Frent_to_own/lists"}