diff options
author | Matthias Beyer <matthias.beyer@ifm.com> | 2022-07-15 17:28:05 +0200 |
---|---|---|
committer | Matthias Beyer <matthias.beyer@ifm.com> | 2022-08-30 13:52:16 +0200 |
commit | 49aac61a251a95db7bc8e8b3589caa1a99db682d (patch) | |
tree | 835ae93fa00b14f09a38f687ad5cd0aca1921646 /crates/core/tedge_api/examples/print_config.rs | |
parent | 1f898e1459a1ab451aac7ef09bd1bf0585172124 (diff) | |
parent | ed1808a9be40210b4d4d3e304f2582a7883b3211 (diff) |
Merge 'feature/add_tedge_api_only' into integrate-feature-api
This merge introduces the thin-edge.io API definition to the codebase.
The merge is done to an integration-branch because of the longevity of
the `feature/add_tedge_api_only` branch, which branched off of `main` in
February 2022.
Because of the long development time, `Cargo.lock` has now conflicts.
We cannot rebase the feature branch anymore, as it would only be effort
that can be prevented by an integration branch such as this.
So, here we introduce the API. This API does _only_ define an interface
how thin-edge.io plugins can be written in a way so they can be used
within the thin-edge.io ecosystem. That means, by using this API, a
plugin author gets the following things for free (these are high-level
bullet points):
* Running their plugin concurrently to other components/plugins of
thin-edge.io
* Sending messages to other components of thin-edge.io
* These messages are typed. This means that they are normal rust
objects. A plugin author does not have to concern themselves with
serialization and deserialization of messages, as there is none
* Message passing is lightweight, no external processes are needed and
sending tons (literally thousands) of messages is not a problem
* Receiving messages from other components of thin-edge.io
* Concurrently
* handling them in an asynchronous way
* without de/serialization overhead
* Safety from crashes. If a plugin crashes, it does not bring down the
rest of the application. All other plugins continue to run
* Compatibility of components is a compiletime assurance!
* A clear shutdown path, if a shutdown was requested for the application
Besides these rather technical points, we get the following (very high
level) benefits:
* Error handling is uniform and streamlined. Providing excellent error
messages to the user is a matter of writing down good error messages,
not of implementing good error handling
* Logging is uniform over all components of the software
* Tracing how a message propagated through the software is easily
doable, as only one process is involved and the excellent `tracing`
ecosystem provides the heavy lifting for us
* runtime performance analytics a developer might want to do is easy
with `tracing` as well
* High performance is ensured via the `tokio` runtime, having tons of
tasks running in a concurrent way is handled by the runtime, a
developer has not to concern themselves with it
All changes that are merged with this commit are made under the DCO and
_not_ under any CLA.
DCO:
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
Signed-off-by: Marcel Müller <m.mueller@ifm.com>
Signed-off-by: Matthias Beyer <matthias.beyer@ifm.com>
Diffstat (limited to 'crates/core/tedge_api/examples/print_config.rs')
-rw-r--r-- | crates/core/tedge_api/examples/print_config.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/crates/core/tedge_api/examples/print_config.rs b/crates/core/tedge_api/examples/print_config.rs new file mode 100644 index 00000000..8be855e0 --- /dev/null +++ b/crates/core/tedge_api/examples/print_config.rs @@ -0,0 +1,150 @@ +#![allow(dead_code, unused)] +use std::collections::HashMap; + +use nu_ansi_term::Color; +use pretty::Arena; +use tedge_api::{ + config::{AsConfig, ConfigDescription, ConfigKind}, + Config, +}; +struct Port(u64); + +impl AsConfig for Port { + fn as_config() -> ConfigDescription { + ConfigDescription::new( + String::from("Integer"), + ConfigKind::Integer, + Some("A TCP port number is an integer between 0 and 65535"), + ) + } +} + +struct VHost; + +impl AsConfig for VHost { + fn as_config() -> ConfigDescription { + ConfigDescription::new( + String::from("VHost"), + ConfigKind::Struct(vec![("name", None, String::as_config())]), + Some("A virtual host definition"), + ) + } +} + +fn main() { + let arena = Arena::new(); + + let doc = Vec::<String>::as_config(); + let rendered_doc = doc.as_terminal_doc(&arena); + + let mut output = String::new(); + + rendered_doc.render_fmt(80, &mut output).unwrap(); + + println!( + "------- Output for {}", + std::any::type_name::<Vec<String>>() + ); + println!("{}", output); + + let arena = Arena::new(); + + let doc = ConfigDescription::new( + String::from("ServerConfig"), + ConfigKind::Struct(vec![ + ("port", None, Port::as_config()), + ("interface", None, String::as_config()), + ("virtual_hosts", None, Vec::<VHost>::as_config()), + ("headers", None, HashMap::<String, String>::as_config()), + ]), + Some("Specify how the server should be started\n\n## Note\n\nThis is a reallly really loooooooooooooooooong loooooooooooooooooooong new *line*."), + ); + let rendered_doc = doc.as_terminal_doc(&arena); + + let mut output = String::new(); + + rendered_doc.render_fmt(80, &mut output).unwrap(); + + println!( + "Configuration for {} plugin kinds", + Color::White.bold().paint(doc.name()) + ); + println!( + "{}", + Color::White.dimmed().bold().paint(format!( + "=================={}=============", + std::iter::repeat('=') + .take(doc.name().len()) + .collect::<String>() + )) + ); + println!("------- Output for ServerConfig"); + println!("{}", output); + let arena = Arena::new(); + + #[derive(Config)] + #[config(tag = "type")] + /// An Nginx virtual host + /// + /// # Note + /// + /// This is an example and as such is nonsense + enum NginxVHost { + /// A simple host consisting of a string + Simple(String), + /// A more complex host that can also specify its port + Complex { + /// the name of the VHost + name: String, + port: Port, + }, + UndocumentedComplex { + num: u16, + foo: f32, + }, + } + + #[derive(Config)] + #[config(untagged)] + enum DebugLevel { + /// Enables debug output + /// + /// And info of course + Debug, + /// Only pertinent information will be logged + Info, + /// A custom debug level + Custom(String), + } + + #[derive(Config)] + struct NginxConfig { + vhosts: Vec<NginxVHost>, + debug_level: DebugLevel, + allow_priv_ports: bool, + } + + let doc = NginxConfig::as_config(); + let rendered_doc = doc.as_terminal_doc(&arena); + + let mut output = String::new(); + + rendered_doc.render_fmt(80, &mut output).unwrap(); + + println!("------- Output for NginxConfig"); + println!( + "Configuration for {} plugin kinds", + Color::White.bold().paint(doc.name()) + ); + println!( + "{}", + Color::White.dimmed().bold().paint(format!( + "=================={}=============", + std::iter::repeat('=') + .take(doc.name().len()) + .collect::<String>() + )) + ); + println!("{}", output); + println!("-------"); +} |