I am a newbie with RUST but I have experience with C/C++. I have a simple C++ library which do the communication to a server (simple client/server communication).
For learning RUST I want to write the library and a small main application in RUST.
The library I want to realize as a module (pub mod mylib {}) and "include" this with "extern crate mylib;" in the main.rs.
As far as good. I want to save the communication parameter (IP, port) inside the module with an initialization function. But how can I create global variables inside the module? I always get an error "expected identifier, found keyword" when I do the declaration outside of a function.
To expand a little on Alice's answer, the main function will typically create various shared resources, such as communication channels, and data shared by Arc. When threads are created clones of the Arc pointers, or channel values, are moved into the closure, so the threads can use the channels to communicate or share data by Arc and possibly protected by Mutex or RwLock (if it is mutable).
Oh lord, it is very difficult to understand how to write a "library" in RUST. I think I have a general problem in understanding the structure of RUST.
What I want is to have client that communicates with an server. The communication protocol should encapsulate in a "library". What is the correct word for "library" in RUST? Module, Crate?
In C++ my library contains the code for the protocol and variables like IP, port, etc. Then I have a main.cpp where I do an instance of my library, call a init function with the arguments IP and port and then I can call functions like get_version that sends a request to the server and returns a version string.
How can I realize that in RUST?
My trials:
main.rs:
extern crate my_protocol;
use my_protocol::ep;
fn main() {
println!("Hello ep!");
let mut my_data = ep::EpData {
host_addr: String::from("192.168.0.20"),
host_port: 9885,
};
my_data.set_host_addr(String::from("192.168.0.50")); // only for testing
my_data.set_host_port(9885); // only for testing
ep::init();
}
I don't want to have the IP and port outside of my module. I want to save this values inside the module and access them inside the module. How can I realize that?
It depends on how you want to use your library. If it's specific to a single project, you probably want to write is as a module, in which case you'd just include my_protocol.rs in the project's src directory and write mod my_protocol; into main.rs.
If you want a reusable library that works with multiple projects, it needs to be an independent Cargo project with its own Cargo.toml, src directory, etc¹. A reference to this project goes into the [dependencies] section of Cargo.toml in each project that uses the library, and you write use my_protocol::ep; in their source files.
It's extremely rare to need an extern crate declaration in your source code these days; it's a holdover from before Cargo was fully developed.
¹ Cargo's "workspaces" feature can help manage this, but I won't go into that here.
Generally, for this kind of stuff, you should define a struct and define your methods on the struct. Then, any shared data can be fields of the struct.
Main would then call the methods by creating an instance of the struct and using the methods on it.