Giter Site home page Giter Site logo

readonly's Introduction

Readonly

github crates.io docs.rs build status

This crate provides an attribute macro to expose struct fields that are readable and writable from within the same module but readable only outside the module.

[dependencies]
readonly = "0.2"

Syntax

Place #[readonly::make] on a braced struct or tuple struct. This will make all fields of the struct publicly readable according to their individual visibility specifiers, but not writable from other modules.

mod m {
    #[readonly::make]
    pub struct S {
        pub n: i32,
    }

    impl S {
        pub fn demo(&mut self) {
            // Can read and write from inside the same module.
            println!("{}", self.n);
            self.n += 1;
        }
    }
}

fn demo(s: &mut m::S) {
    // From outside the module, can only read.
    println!("{}", s.n);

    // Does not compile:
    //s.n += 1;
}

The error appears as follows.

error[E0594]: cannot assign to data in a dereference of `m::S`
  --> readme.rs:21:5
   |
21 |     s.n += 1;
   |     ^^^^^^^^ cannot assign

Optionally, place #[readonly] on individual struct fields to make just those fields publicly readable, without affecting other fields of the struct.

#[readonly::make]
pub struct S {
    // This field can be read (but not written) by super.
    #[readonly]
    pub(super) readable: i32,

    // This field can be neither read nor written by other modules.
    private: i32,
}

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

readonly's People

Contributors

dtolnay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

readonly's Issues

Feature request: ability to call constructor from another module

Given

#[readonly::make]
pub struct Foo {
    pub bar: i32
}

I want to be able to construct Foo objects outside the module which cannot then be modified; if I invoke Foo {bar: 123} from outside the module I get field bar of struct mymodule::Foo is private. Can work around this by defining new, but this doesn't have named arguments which are useful for non-trivial types.

Make readonly fields visible in rustdoc

By making them pub in the case of #[cfg(rustdoc)].

For example with the invocation from the readme:

#[readonly::make]
pub struct S {
    pub n: i32,
}

we will need to generate:

  #[repr(C)]
  pub struct S {
+     #[cfg(not(rustdoc))]
      n: i32,
+     #[cfg(rustdoc)]
+     pub n: i32,
  }

  #[repr(C)]
  pub struct ReadOnlyS {
      pub n: i32,
  }

  impl core::ops::Deref for S {
      type Target = ReadOnlyS;
      ...
  }

Currently blocked on rust-lang/rust#43781.

Error on pattern destructuring on readonly structs

First, I love this crate and I am using it everywhere.

I've this scenario where

#[readonly::make]
#[derive(Debug, Default)]
pub struct TallySpecificType { 
pub a_field: usize,
}

And somewhere along the way, I want to

let TallySpecificType { a_field } = some_tally_specific_type;

But I get erros on a_field being a private-field. I understand that this prevents me from constructing this struct "outside" of
it, which is something I want to keep, but the destructuring should be possible irregardless.

What am I missing here? Some &*? Or is there as misunderstanding somehow?

What is the point?

I don't really understand what is the point in having struct members be read-only? If you always want something to have a constant value, what is the problem in Rust to defined a constant in a module scope?

If we make a struct like

mod m {
    #[readonly::make]
    pub struct String {
        pub max_length: i32,
    }

    impl String {
        fn new() -> String {
            String {
                max_length: 5
            }
        }
    }
}

what are the advantages over

mod m {
    pub const STRING_MAX_LENGTH: i32 = 5;
}

Or, another case, in case the max_length is mutable within String, what are the advantages of readonly over a getter?

mod m {
    pub struct String {
        pub max_length: i32,
    }

    impl String {
        fn max_length(&self) -> i32 {
            self.max_length
        }

        fn max_length_ref(&self) -> &i32 {
            &self.max_length
        }
    }
}

Or maybe there are other profits which the crate's README and documentation did not explain? Well, there are no explanation at all, about why is it better over something else. If there are really good use cases or major problems that it solves, I think it is worth to be in the language itself (or there is an RFC about it?).

Though I find this crate interesting, I am not sure where and when I need to use it. Adding some explanation and comparisons would be good I guess.

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.