Per creare un Webservice in Rust che utilizza Axis (un framework per la definizione di servizi web basato su XML Schema) e Diesel (un ORM per database SQLite), dobbiamo seguire alcuni passaggi. Tuttavia, è 
importante notare che l'uso diretto di Axis con Diesel non è il modo più comune o consigliato per creare servizi web in Rust. Più spesso si usa Axum o Rocket come framework principale.

Tuttavia, posso mostrarti un esempio molto simplificato di come potresti iniziare a strutturare il tuo progetto utilizzando Diesel con SQLite3 e una libreria esterna per la definizione dei servizi web. Per 
brevità, utilizzeremo `axum`, che è uno dei framework più popolari per creare servizi web in Rust.

### Prerequisiti

1. Installa Rust: https://www.rust-lang.org/tools/install
2. Crea un nuovo progetto con Cargo:
   ```sh
   cargo new rust_sqlite_webserver
   cd rust_sqlite_webserver
   ```

3. Aggiungi le dipendenze al file `Cargo.toml`:

```toml
[dependencies]
axum = "0.6"
tokio = { version = "1", features = ["full"] }
diesel = { version = "2.0", features = ["sqlite"] }
dotenv = "0.15"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[build-dependencies]
diesel_cli = { version = "2.0", features = ["sqlite"] }

[[bin]]
name = "main"
path = "src/main.rs"
```

### Schema di Database

Creiamo un semplice schema per un database SQLite3 con Diesel.

1. Crea il file `schema.rs` in una nuova directory `src/schema/`.

```rust
// src/schema/users.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email TEXT NOT NULL UNIQUE
);
```

2. Genera i modelli Diesel:

```sh
cargo run --bin diesel_cli setup
cargo run --bin diesel_cli migrate
```

### Creazione del Servizio Web con Axum

1. Crea un file `main.rs` nella directory `src/`.

```rust
use axum::{
    routing::get,
    Router,
};
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use std::env;

mod schema;
mod models;

// Importiamo i modelli generati da Diesel
use self::schema::users::dsl::*;

#[derive(Serialize)]
struct User {
    id: i32,
    name: String,
    email: String,
}

impl From<models::User> for User {
    fn from(user: models::User) -> Self {
        User {
            id: user.id,
            name: user.name,
            email: user.email,
        }
    }
}

#[derive(Deserialize, Insertable)]
#[diesel(table_name = users)]
struct NewUser {
    name: String,
    email: String,
}

async fn get_users() -> impl axum::response::IntoResponse {
    let conn = establish_connection();
    let results = users.load::<models::User>(&conn).expect("Error loading users");

    (axum::http::StatusCode::OK, axum::Json(results.into_iter().map(User::from).collect()))
}

async fn create_user(user: axum::Json<NewUser>) -> impl axum::response::IntoResponse {
    let conn = establish_connection();
    let new_user = user.0;
    diesel::insert_into(users)
        .values(&new_user)
        .get_result::<models::User>(&conn)
        .expect("Error creating new user");

    (axum::http::StatusCode::CREATED, axum::Json(User::from(new_user)))
}

fn establish_connection() -> SqliteConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    SqliteConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}

#[tokio::main]
async fn main() {
    // Set the `RUST_LOG` environment variable if you want to see logs
    env_logger::init();

    let app = Router::new()
        .route("/users", get(get_users).post(create_user));

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}
```

### Esecuzione del Progetto

1. Crea un file `.env` nella directory root con la seguente riga:

```sh
DATABASE_URL=sqlite://db.sqlite3
```

2. Esegui il progetto:

```sh
cargo run
```

Ora, puoi accedere al tuo servizio web:

- Per ottenere tutti gli utenti: `GET http://localhost:3000/users`
- Per creare un nuovo utente: `POST http://localhost:3000/users` con il corpo JSON:
  ```json
  {
    "name": "John Doe",
    "email": "john.doe@example.com"
  }
  ```

Questo esempio mostra come iniziare a strutturare un servizio web in Rust utilizzando Axum, Diesel con SQLite3. Ricorda che questo è solo un punto di partenza e potrebbe essere esteso o modificato per 
soddisfare le tue specifiche esigenze.

>>> il mio progetto prevede vari file binari, oltre al webservice come posso gestire piu' binari?                                              
Se il tuo progetto in Rust contiene diversi file binari (ad esempio, un client e un server separati), puoi organizzarli in moduli all'interno del tuo progetto. Ogni modulo può essere compilato come un file 
binario separato.

Ecco come farlo:

1. **Struttura del Progetto**:
   Organizza il tuo progetto in una directory `src` con sottodirectory per i vari binari e moduli. Ad esempio:

   ```
   rust_project/
   ├── src/
   │   ├── main.rs
   │   ├── client/
   │   │   └── main.rs
   │   ├── server/
   │   │   └── main.rs
   │   └── common/
   │       └── lib.rs
   ├── Cargo.toml
   └── .env
   ```

2. **Creazione dei Binari**:
   Ogni sottodirectory con un file `main.rs` può essere considerata un binario separato.

3. **Cargo.toml**:
   Configura il tuo `Cargo.toml` per gestire i vari binari.

   ```toml
   [package]
   name = "rust_project"
   version = "0.1.0"
   edition = "2018"

   [dependencies]
   axum = "0.6"
   tokio = { version = "1", features = ["full"] }
   diesel = { version = "2.0", features = ["sqlite"] }
   serde = { version = "1.0", features = ["derive"] }
   serde_json = "1.0"

   [build-dependencies]
   diesel_cli = { version = "2.0", features = ["sqlite"] }

   [[bin]]
   name = "server"
   path = "src/server/main.rs"

   [[bin]]
   name = "client"
   path = "src/client/main.rs"
   ```

4. **Esecuzione dei Binari**:
   Puoi ora compilare e eseguire i binari separati.

   ```sh
   cargo build --release
   ./target/release/server
   ./target/release/client
   ```

5. **Moduli Comuni**:
   Se hai moduli comuni che vengono utilizzati da più binari, puoi organizzarli in una directory `common` e importarli nei vari binari.

   ```rust
   // src/common/lib.rs
   pub mod common_module {
       pub fn common_function() {
           println!("This is a common function");
       }
   }
   ```

   Allora, puoi importare questo modulo in altri binari:

   ```rust
   // src/server/main.rs
   extern crate rust_project;

   use rust_project::common::lib as common;

   fn main() {
       common::common_function();
   }
   ```

6. **File `.env`**:
   Puoi avere un file `.env` nella directory root del progetto per gestire le variabili d'ambiente comuni, e poi specificare variabili d'ambiente separate per ogni binario in sottodirectory.

   ```sh
   # .env
   DATABASE_URL=sqlite://db.sqlite3

   # src/server/.env
   SERVER_PORT=3000

   # src/client/.env
   CLIENT_IP=localhost
   ```

Questo approccio ti permette di mantenere una struttura organizzata per i tuoi progetti multi-binari in Rust, facilitando la gestione e il sviluppo di diverse parti del tuo progetto.

