Rauts is library for building [Open Charge Point Protocol][OCPP] (OCPP) servers and clients. OCPP is de facto communication standard between chargers of electric vehicles (EV) and the servers managing the chargers.
The project is in very early stage. Currently, the focus is on designing a satisfying API for routing requests and responses.
Clone the repository and run one of the examples:
$ git clone https://github.com/OrangeTux/rauts.git
$ cd rauts
$ cargo run --example handler_func_with_multiple_arguments
The project is heavily inspired by "magic handler functions" as implemented in Axum and other projects.
A regular function automatically implements the Handler
trait when:
- It receives zero or more arguments. All arguments must implement
rauts::extract::FromRequest
. - It must return something that implements
rauts::response::IntoResponse
These are valid examples of handler functions:
use rauts::ocpp::v16::{
call::{Authorize, Call, Payload},
call_result,
call_result::{IdTagInfo, Status},
Action,
};
/// This `Handler` doesn't receive any arguments.
fn heartbeat() -> call_result::Heartbeat {
call_result::Heartbeat {
current_time: Utc::now(),
}
}
/// This `Handler` has one argument of type `Request`.
fn authorize(request: Request) -> call_result::Authorize {
let status = match request.call.payload {
Payload::Authorize(payload) => {
if payload.id_tag.as_str() == "454564564" {
Status::Accepted
} else {
Status::Invalid
}
}
_ => Status::Invalid,
};
call_result::Authorize {
id_tag_info: IdTagInfo {
status,
parent_id_tag: None,
expiry_date: None,
},
}
}
/// This `Handler` receives two arguments. Types of both arguments implement `rauts::extract::FromRequest`.
fn also_authorize(
Authorize { id_tag }: Authorize,
ChargerId(charger_id): ChargerId,
) -> call_result::Authorize {
let status = match (id_tag.as_str(), charger_id.as_str()) {
("424242", "Alfen 123") => Status::Accepted,
_ => Status::Invalid,
};
call_result::Authorize {
id_tag_info: IdTagInfo {
status,
parent_id_tag: None,
expiry_date: None,
},
}
}
Handler
s are registered at a Router
. The Router
is responsible for calling the correct Handler
when the Router
receives a Request
.
use rauts::extract::{ChargerId, Request}
use rauts::handler::IntoHandler;
use rauts::Router;
use rauts::ocpp::v16::{
call::{Call, Heartbeat},
Action
}
let router: Router<Action> =
Router::new()
.register(heartbeat.into_handler(), Action::Heartbeat)
.register(authorize.into_handler(), Action::Authorize);
let call: Call = Heartbeat {}.into();
let request = Request {
call,
charger_id: ChargerId("Alfen 123".to_string()),
};
router.route(&request).unwrap();