Git Product home page Git Product logo

anymap's Introduction

Functions added by the fork:

I found myself in a situation where I need to test if a given AnyMap contains a set of types. As we cannot work with types as concrete values, raw_* methods were added that work with the underling TypeIds of the map.

AnyMap.raw_contains(&self, type_id: TypeId) // bool
AnyMap.raw_contains_all(&self, type_ids: &[TypeId]) // bool
AnyMap.raw_keys(&self); // Keys<'_, TypeId, Box<A>>
AnyMap.raw_get::<T>(&self, type_id: TypeId) // Option<&T>
AnyMap.raw_get_mut::<T>(&mut self, type_id: TypeId) // Option<&mut T>

Original README.md:

AnyMap, a safe and convenient store for one value of each type

Build Status

If you’re familiar with Go and Go web frameworks, you may have come across the common “environment” pattern for storing data related to the request. It’s typically something like map[string]interface{} and is accessed with arbitrary strings which may clash and type assertions which are a little unwieldy and must be used very carefully. (Personally I would consider that it is just asking for things to blow up in your face.) In a language like Go, lacking in generics, this is the best that can be done; such a thing cannot possibly be made safe without generics.

As another example of such an interface, JavaScript objects are exactly the same—a mapping of string keys to arbitrary values. (There it is actually more dangerous, because methods and fields/attributes/properties are on the same plane.)

Fortunately, we can do better than these things in Rust. Our type system is quite equal to easy, robust expression of such problems.

The AnyMap type is a friendly wrapper around a HashMap<TypeId, Box<Any>>, exposing a nice, easy typed interface, perfectly safe and absolutely robust.

What this means is that in an AnyMap you may store zero or one values for every type.

Instructions

Cargo all the way: it is anymap on crates.io.

Unsafe code in this library

This library uses a fair bit of unsafe code for several reasons:

  • To support Any and CloneAny, unsafe code is required (because of how the downcast methods are defined in impl Any rather than being trait methods; I think this is kind of a historical detail of the structure of std::any::Any); if you wanted to ditch Clone support this unsafety could be removed.

  • In the interests of performance, skipping various checks that are unnecessary because of the invariants of the data structure (no need to check the type ID when it’s been statically ensured by being used as the hash map key) and simplifying hashing (type IDs are already good hashes, no need to mangle them through SipHash).

It’s not possible to remove all unsafety from this library without also removing some of the functionality. Still, at the cost of the CloneAny functionality, the raw interface and maybe the concurrency support, you can definitely remove all unsafe code. Here’s how you could do it:

  • Remove the genericness of it all;
  • Merge anymap::raw into the normal interface, flattening it;
  • Change things like .map(|any| unsafe { any.downcast_unchecked() }) to .and_then(|any| any.downcast()) (performance cost: one extra superfluous type ID comparison, indirect);
  • Ditch the TypeIdHasher since transmuting a TypeId is right out (cost: SIP mangling of a u64 on every access).

Yeah, the performance costs of going safe are quite small. The more serious matters are the loss of Clone and maybe Send + Sync.

But frankly, if you wanted to do all this it’d be easier and faster to write it from scratch. The core of the library is actually really simple and perfectly safe, as can be seen in src/lib.rs in the first commit (note that that code won’t run without a few syntactic alterations; it was from well before Rust 1.0 and has things like Any:'static where now we have Any + 'static).

Author

Chris Morgan (chris-morgan) is the primary author and maintainer of AnyMap.

License

This library is distributed under similar terms to Rust: dual licensed under the MIT license and the Apache license (version 2.0).

See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.

anymap's People

Contributors

chris-morgan avatar drbawb avatar hellow554 avatar reem avatar tivek avatar tomassedovic avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.