From 0702ab1829188c23ccdceb54ff6ac6786ecdff52 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 20 Dec 2016 17:29:35 -0800 Subject: [PATCH] Utility crate for things that don't fit anywhere else. Helper struct to emcapsulate one time initializations with a RefCell of an Option. --- util/Cargo.toml | 4 ++++ util/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 util/Cargo.toml create mode 100644 util/src/lib.rs diff --git a/util/Cargo.toml b/util/Cargo.toml new file mode 100644 index 000000000..a21d5e340 --- /dev/null +++ b/util/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "grin_util" +version = "0.1.0" +authors = ["Ignotus Peverell "] diff --git a/util/src/lib.rs b/util/src/lib.rs new file mode 100644 index 000000000..f8bb8d913 --- /dev/null +++ b/util/src/lib.rs @@ -0,0 +1,49 @@ +// Copyright 2016 The Grin Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Various low-level utilities that factor Rust patterns that are frequent +/// within the grin codebase. + +use std::cell::{RefCell, Ref}; +#[allow(unused_imports)] +use std::ops::Deref; + +// Encapsulation of a RefCell> for one-time initialization after +// construction. This implementation will purposefully fail hard if not used +// properly, for example if it's not initialized before being first used +// (borrowed). +pub struct OneTime { + inner: RefCell>, +} + +unsafe impl Sync for OneTime {} +unsafe impl Send for OneTime {} + +impl OneTime { + /// Builds a new uninitialized OneTime. + pub fn new() -> OneTime { + OneTime { inner: RefCell::new(None) } + } + + /// Initializes the OneTime, should only be called once after construction. + pub fn init(&self, value: T) { + let mut inner_mut = self.inner.borrow_mut(); + *inner_mut = Some(value); + } + + /// Borrows the OneTime, should only be called after initialization. + pub fn borrow(&self) -> Ref { + Ref::map(self.inner.borrow(), |o| o.as_ref().unwrap()) + } +}