Defining a struct member with private module types - rust

I've been using a bunch of modules that have a build() function which returns a struct. However, when I try to create my own "super" struct to bundle them together, I run into the error module `xxx` is private rustc(E0603). If there is a trait I can pass the individual variable as a parameter but cannot figure out how to define/box it up for a struct.
The current example of this I'm hitting is when creating a hyper client.
// Error due to privacy and cannot use the trait to define the member type
// Both the "hyper_rustls::connector" and "hyper::client::connect::http" modules are private.
struct SecureClient {
client: hyper::client::Client<
hyper_rustls::connector::HttpsConnector<hyper::client::connect::http::HttpConnector>>
}
// Works, but passing the client everywhere as an individual variable is not realistic.
fn use_client(client: hyper::client::Client<impl hyper::client::connect::Connect>) -> () {
()
}
let https_conn = hyper_rustls::HttpsConnector::new(4);
let client: hyper::client::Client<_, hyper::Body> = hyper::Client::builder().build(https_conn);
Being newish to Rust, I'm struggling to figure out what the proper jargon is for what I'm trying to do, let alone make it work. Links to any docs or code examples about this would be appreciated.
Thanks

I'm not sure what you want to do, but you can use the public re-export hyper_rustls::HttpsConnector instead of the private hyper_rustls::connector::HttpsConnector and the public re-export hyper::client::HttpConnector instead of the private hyper::client::connect::http::HttpConnector.
You can read about re-exports here: https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html#re-exporting-names-with-pub-use

Related

How to make macro import/use struct in any place it's used?

Suppose I have the following code inside a module:
struct A{
}
#[macro_export]
macro_rules! profile {
($variable_name:tt, $expression:expr) => {
let a = A{};
}
}
so it'd be in a/a.rs, to the side of a/mod.rs which exports a::A and also exports the macro.
The problem is that when I use this macro on other modules like b/b.rs, I'd have to use super::a::A before using the macro.
I could change let a = A{}; on the macro to let a = self::a::A{};. However, it'd not work on all modules, and certainly not for users of this library that use this library in their code.
How can I specify let a = something::something::A{}; in a way that it works anywhere inside my library as well for users of this lib?
In declarative macros specifically, you can use the $crate metavariable to reference the crate the macro is defined in, and then use the absolute path of the item. This will work both inside and outside of your library. For example, if your struct A is defined in your library at the path module_a::module_b::A, you would use:
struct A{
}
#[macro_export]
macro_rules! profile {
($variable_name:tt, $expression:expr) => {
let a = $crate::module_a::module_b::A{};
}
}
Here's the relevant section of the Rust reference guide.

How do I use an IOC container with typescript generics in node?

I am attempting to use container-ioc, but am happy to use any package supplying IoC. I cannot find any examples that use typescript generics. Basically, I want:
interface A<T> {
foo();
}
class A<T> {
foo() {
}
}
interface B<T> {
bar: A<T>;
}
class B<T> {
bar: A<T>;
constructor(param: A<T>) {
this.bar = param;
}
}
where I can set up an IoC container to inject A into B. I am using typescript in a node app. I have syntax that seems to parse at least, but cannot craft the container resolve() as I don't know how to pass the generic parameter. Not to mention, I'm not sure whether this is actually supported.
So, I have a workaround that works for my situation. Firstly, I set a symbol for the generic type with const MyFoo = Symbol("Foo<My>"). Then, I use a factory constructor when registering the type:
container.register([
{ token: MyBar, useFactory: () => new Bar<My>() },
token: MyFoo, useFactory: () => new Foo<My>( container.resolve(MyBar) )}]);
Finally, I do not #inject the parameter on the constructor. This method means that I need to know what generic types I will be using beforehand. In my case, I do: my generic types implement an entity repository and related classes, and my entities are the generic parameters. I'd prefer to not have yet another place to maintain when setting up new entities, so I am leaving this answer unaccepted in case someone has a better solution.

Struct declaration order

If I define structs at the module level, I can reference not-yet defined structs.
struct S {
ComesLater c;
}
struct ComesLater {}
But If I do the same inside an unittest or a function block, it doesn't work:
unittest {
struct S {
ComesLater c;
}
struct ComesLater {}
}
Error: undefined identifier 'ComesLater'
Why is that? How can I get order-independent declarations inside functions? Is there some kind of forward-declaration in d? I need this because I generate structs using mixin and ordering the declarations in the order of their inner-dependencies would be quite some effort, sometimes impossible, if there are circularly referencing structs. (using pointers.)
Declarations inside functions, unittests, or anywhere else that statements can actually be executed are indeed order-dependent because their values may depend on the code before them running. Think of a local variable:
int a;
writeln(a);
a = b;
int b = get_user_line();
If order wasn't important there, when would the two functions get called? Would the user be asked for a line before the writeln as the declarations are rewritten?
The current behavior of making b an undefined variable error keeps it simple and straightforward.
It works independent of order in other contexts because there is no executable code that it can depend on, so there's no behavior that can change if the compiler needs to internally think about it differently.
So:
How can I get order-independent declarations inside functions?
Change the context such that there is no executable code... put it all inside another struct!
void main() { // or unittest { }
struct Holder {
static struct S {
C c;
}
static struct C {}
}
}
Since execution happens around the holder and doesn't happen inside it, the order of declaration inside doesn't matter again. Since you can define almost anything inside a struct, you can use this for variables, functions, other structs, and so on. Basically all you have to do is wrap your existing code inside the struct Holder {} brackets.
By making everything static inside, you can just use it like a container and reference the stuff with Holder.S, etc., on the outside.

Declaring a map in a separate file and reading its contents

I'm trying to declare a map in a separate file, and then access it from my main function.
I want Rust's equivalent (or whatever comes closest) to this C++ map:
static const std::map<std::string, std::vector<std::string>> table = {
{ "a", { "foo" } },
{ "e", { "bar", "baz" } }
};
This is my attempt in Rust.
table.rs
use std::container::Map;
pub static table: &'static Map<~str, ~[~str]> = (~[
(~"a", ~[~"foo"]),
(~"e", ~[~"bar", ~"baz"])
]).move_iter().collect();
main.rs
mod table;
fn main() {
println(fmt!("%?", table::table));
}
The above gives two compiler errors in table.rs, saying "constant contains unimplemented expression type".
I also have the feeling that the map declaration is less than optimal for the purpose.
Finally, I'm using Rust 0.8.
As Chris Morgan noted, rust doesn't allow you to run user code in order to initialize global variables before main is entered, unlike C++. So you are mostly limited to primitive types that you can initialize with literal expressions. This is, afaik, part of the design and unlikely to change, even though the particular error message is probably not final.
Depending on your use case, you might want to change your code so you're manually passing your map as an argument to all the functions that will want to use it (ugh!), use task-local storage to initialize a tls slot with your map early on and then refer to it later in the same task (ugh?), or use unsafe code and a static mut variable to do much the same with your map wrapped in an Option maybe so it can start its life as None (ugh!).

Calling Properties from Struct in c#

i have a structure defined, which contains a public field and a public property named _one and One respectively, now i instantiate the struct in the main function (not creating new object), and called the Property from the struct, i am getting the compile time error saying use of unassigned local variable One, however when i called the field _one, it works pretty expected here what i am doing:
public struct myStruct
{
public int _one;
public int One
{
get { return _one; }
set { _one = value; }
}
public void Display()
{
Console.WriteLine(One);
}
}
static void Main(string[] args)
{
myStruct _struct;
_struct.One = 2; // Does not works
_struct._one = 2; // Works fine
}
can anyone explain whats the reason behind this, could not understand the concept.
You need to initialize the struct in order for the property to be accessible - _struct has a default value otherwise:
myStruct _struct = new myStruct();
By the way - mutable value types are evil.
This is unintuitive behavior, but it is permitted by the rules of Definite assignment checking. Described in excruciating detail in section 5.3 of the C# Language Specification. The key phrase, early in the chapter is:
In additional to the rules above, the following rules apply to struct-type variables and their instance variables:
- An instance variable is considered definitely assigned if its containing struct-type variable is considered definitely assigned.
- A struct-type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.
It is the latter rule that permits this. In other words, you can also initialize a struct by assigning all of its variables. You can see this by trying these snippets:
myStruct _struct = new myStruct();
_struct.Display(); // fine by the 1st bullet
myStruct _struct;
_struct.Display(); // bad
myStruct _struct;
_struct._one = 2;
_struct.Display(); // fine by the 2nd bullet
So you don't get CS0165 by assigning the field because that would disallow initializing the structure by assigning its variables.
The reasons which would favor using read-write properties instead of exposed fields in class definitions do not apply to structures, since they can support neither inheritance nor update notifications, and the mutability of a struct's field depends upon the mutability of the struct instance, regardless of whether the field is exposed or not. If a struct is supposed to represent a group of related but freely-independently-modifiable variables, it should simply expose those variables as fields. If a property with a backing field is supposed to be read-only, the constructor should set the backing field directly, rather than via property setter.

Resources