hdbconnect_impl/protocol/parts/
client_info.rs1use crate::{
2 HdbResult,
3 protocol::parts::hdb_value::{emit_length_and_string, string_length},
4};
5use std::collections::HashMap;
6use std::env;
7use std::path::Path;
8
9#[derive(Clone, Debug)]
10pub(crate) struct ClientInfo(HashMap<ClientInfoKey, String>);
11
12impl Default for ClientInfo {
13 fn default() -> Self {
14 let mut ci = Self(HashMap::<ClientInfoKey, String>::new());
15
16 if let Some(os_str) = env::args_os().next() {
17 let p = Path::new(&os_str);
18 if let Some(s) = p.file_name() {
19 ci.set_application(s.to_string_lossy());
20 }
21 }
22 if cfg!(feature = "async") {
23 ci.set_driver("hdbconnect_async");
24 ci.set_driver_version(&format!("hdbconnect_impl = {}", env!("CARGO_PKG_VERSION")));
25 ci.set_driver_info("https://crates.io/crates/hdbconnect_async");
26 } else {
27 ci.set_driver("hdbconnect");
28 ci.set_driver_version(&format!("hdbconnect_impl = {}", env!("CARGO_PKG_VERSION")));
29 ci.set_driver_info("https://crates.io/crates/hdbconnect");
30 }
31
32 ci
33 }
34}
35
36impl std::fmt::Display for ClientInfo {
37 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
38 for (k, v) in &self.0 {
39 writeln!(f, "{k:?} = {v}")?;
40 }
41 Ok(())
42 }
43}
44
45impl ClientInfo {
46 pub fn set_application<S: AsRef<str>>(&mut self, application: S) {
47 self.set(ClientInfoKey::Application, application.as_ref());
48 }
49 pub fn set_application_version(&mut self, application_version: &str) {
50 self.set(ClientInfoKey::ApplicationVersion, application_version);
51 }
52 pub fn set_application_source(&mut self, application_source: &str) {
53 self.set(ClientInfoKey::ApplicationSource, application_source);
54 }
55 pub fn set_application_user(&mut self, application_user: &str) {
56 self.set(ClientInfoKey::ApplicationUser, application_user);
57 }
58 fn set_driver(&mut self, driver: &str) {
59 self.set(ClientInfoKey::Driver, driver);
60 }
61 fn set_driver_info(&mut self, driver_info: &str) {
62 self.set(ClientInfoKey::DriverInfo, driver_info);
63 }
64 fn set_driver_version(&mut self, driver_version: &str) {
65 self.set(ClientInfoKey::DriverVersion, driver_version);
66 }
67
68 pub fn emit(&self, w: &mut dyn std::io::Write) -> HdbResult<()> {
69 for (key, value) in &self.0 {
70 emit_length_and_string(key, w)?;
71 emit_length_and_string(value, w)?;
72 }
73 Ok(())
74 }
75
76 pub fn size(&self) -> usize {
77 let mut len = 0;
78 for (key, value) in &self.0 {
79 len += string_length(key) + string_length(value);
80 }
81 len
82 }
83 pub fn count(&self) -> usize {
84 self.0.len() * 2
85 }
86
87 fn set(&mut self, key: ClientInfoKey, value: &str) {
88 let value = value.to_string();
89 self.0.insert(key, value);
90 }
91}
92
93#[derive(Clone, Debug, Eq, Hash, PartialEq)]
94enum ClientInfoKey {
95 Application,
96 ApplicationVersion,
97 ApplicationSource,
98 ApplicationUser,
99 Driver,
100 DriverInfo,
101 DriverVersion,
102}
103impl AsRef<str> for ClientInfoKey {
104 fn as_ref(&self) -> &str {
105 match &self {
106 Self::Application => "APPLICATION",
107 Self::ApplicationVersion => "APPLICATIONVERSION",
108 Self::ApplicationSource => "APPLICATIONSOURCE",
109 Self::ApplicationUser => "APPLICATIONUSER",
110 Self::Driver => "DRIVER",
111 Self::DriverInfo => "DRIVERINFO",
112 Self::DriverVersion => "DRIVERVERSION",
113 }
114 }
115}