Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

Clientless runtime-agnostic architecture #32

Merged
merged 114 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
ae3bc3b
factory dependencies
dmitrii-ubskii Dec 19, 2022
392d864
fixup
dmitrii-ubskii Dec 19, 2022
6cc3442
executor is already shared
dmitrii-ubskii Dec 19, 2022
0286dd4
single executor per client
dmitrii-ubskii Dec 19, 2022
be50f6d
move to crosbeam channel everywhere
dmitrii-ubskii Dec 20, 2022
861fbb5
remove tokio dep from main crate
dmitrii-ubskii Dec 20, 2022
e2b650e
use most explicit coercions
dmitrii-ubskii Dec 20, 2022
8bbd1d8
cleanup
dmitrii-ubskii Dec 21, 2022
c9482cf
Server session pulse & auto-close
dmitrii-ubskii Dec 22, 2022
afb4861
cluster session pulse and auto-close
dmitrii-ubskii Dec 22, 2022
9a210dd
rename
dmitrii-ubskii Dec 22, 2022
45e205f
decouple executor from rpc
dmitrii-ubskii Dec 22, 2022
935ad82
move session_manager into server
dmitrii-ubskii Dec 23, 2022
d75f08b
encapsulation
dmitrii-ubskii Dec 23, 2022
b00214e
revert to yielding sleep
dmitrii-ubskii Dec 23, 2022
773a803
remove unneeded aliases
dmitrii-ubskii Dec 23, 2022
1e030b0
add async single call to tx rpc
dmitrii-ubskii Dec 23, 2022
cf8a163
transaction: async commit and rollback
dmitrii-ubskii Jan 9, 2023
089b61d
remove prints
dmitrii-ubskii Jan 9, 2023
32920fd
naming
dmitrii-ubskii Jan 9, 2023
b26610f
parallel session close requests
dmitrii-ubskii Jan 9, 2023
d0bd284
remove thread pool, use tokio rt
dmitrii-ubskii Jan 10, 2023
d094719
remove print
dmitrii-ubskii Jan 10, 2023
2b4908f
Update dependencies
dmitrii-ubskii Jan 16, 2023
2b48cf1
blocking dispatcher stub
dmitrii-ubskii Jan 18, 2023
aafe355
blocking dispatcher cleanup
dmitrii-ubskii Jan 19, 2023
a9ac84a
move blocking dispatcherfrom rpc to common
dmitrii-ubskii Jan 19, 2023
d0b607f
clean up SyncFuture visibility
dmitrii-ubskii Jan 19, 2023
7a29918
mutexed session manager
dmitrii-ubskii Jan 19, 2023
2883103
ServerSession::force_close
dmitrii-ubskii Jan 19, 2023
2d75e15
cleanup dead code
dmitrii-ubskii Jan 19, 2023
e9fbb9b
force closable sessions
dmitrii-ubskii Jan 19, 2023
72a4f6d
session manager cleanup
dmitrii-ubskii Jan 19, 2023
cb65b2a
renames
dmitrii-ubskii Jan 20, 2023
a0a413b
TransactionRPC BatchingDispatcher
dmitrii-ubskii Jan 20, 2023
971feca
tests
dmitrii-ubskii Jan 23, 2023
cc36885
force close database connections by force closing underlying RPC
dmitrii-ubskii Jan 23, 2023
a34ca49
cluster tests
dmitrii-ubskii Jan 23, 2023
89a178a
internal error
dmitrii-ubskii Jan 23, 2023
bb64374
snapshot wip
dmitrii-ubskii Feb 1, 2023
9903edb
clientless snapshot
dmitrii-ubskii Feb 10, 2023
92b3ca0
move tonic to bgrt, merge tests, misc cleanup
dmitrii-ubskii Feb 15, 2023
eb3d9a9
restructure
dmitrii-ubskii Feb 15, 2023
a191532
restructure + compat test
dmitrii-ubskii Feb 16, 2023
5055099
rearchitecture draft
dmitrii-ubskii Feb 17, 2023
c0575d4
transmitters
dmitrii-ubskii Feb 17, 2023
e993bec
proto serde traits
dmitrii-ubskii Feb 17, 2023
485318f
uncomment test portion
dmitrii-ubskii Feb 17, 2023
1354ce9
remove last tokio dep outside background thread
dmitrii-ubskii Feb 17, 2023
c6075fc
transaction transmitter
dmitrii-ubskii Feb 20, 2023
78ff61f
split transmitter module
dmitrii-ubskii Feb 20, 2023
895ae1f
rename mod transaction => transaction_stream
dmitrii-ubskii Feb 20, 2023
401f551
error propagation in tests/queries
dmitrii-ubskii Feb 20, 2023
35f1e8c
propagate stub send errors
dmitrii-ubskii Feb 20, 2023
623dbd6
message error handling
dmitrii-ubskii Feb 20, 2023
546be82
internal error on unexpected enum variants
dmitrii-ubskii Feb 20, 2023
ae992e6
protobuf deserialization error handling
dmitrii-ubskii Feb 20, 2023
97422b5
update dependencies
dmitrii-ubskii Feb 22, 2023
a312dbb
clean up database + session
dmitrii-ubskii Feb 22, 2023
cd4905f
db & replica info
dmitrii-ubskii Feb 22, 2023
1c3b75e
tighten visibility
dmitrii-ubskii Feb 22, 2023
a42aa3b
move address to common
dmitrii-ubskii Feb 22, 2023
04a9e7f
rpc error handling
dmitrii-ubskii Feb 22, 2023
6f429fc
clean up connection
dmitrii-ubskii Feb 22, 2023
cfb64c7
120
dmitrii-ubskii Feb 22, 2023
fdd65af
format permutation test macro
dmitrii-ubskii Feb 22, 2023
38636bb
generic callback
dmitrii-ubskii Feb 22, 2023
52aeff2
misc cleanup
dmitrii-ubskii Feb 22, 2023
38ea2df
compat test cleanup
dmitrii-ubskii Feb 22, 2023
76a4db4
misc cleanup
dmitrii-ubskii Feb 22, 2023
d180e89
last bits of error cleanup
dmitrii-ubskii Feb 22, 2023
afdd088
unexpected response/request type error messages
dmitrii-ubskii Feb 22, 2023
2468bd6
enum out of bounds error
dmitrii-ubskii Feb 22, 2023
6f2c36e
unknown address error
dmitrii-ubskii Feb 22, 2023
cb62bf1
remove fixmes
dmitrii-ubskii Feb 22, 2023
b2d720e
extract common functionality in tests
dmitrii-ubskii Feb 23, 2023
8e26dc6
accept &str or owned String as db name
dmitrii-ubskii Feb 23, 2023
9fc8aee
remove async-trait dep
dmitrii-ubskii Feb 23, 2023
588b9cf
public conceptmap
dmitrii-ubskii Feb 23, 2023
f2f754d
callcreds => call_credentials
dmitrii-ubskii Feb 23, 2023
bbf57db
rename [CLI] Client Error => [CXN] Connection Error
dmitrii-ubskii Feb 23, 2023
0ca99db
explicit pub(crate) for info structs
dmitrii-ubskii Feb 23, 2023
5428381
removed stray pub
dmitrii-ubskii Feb 23, 2023
90466fe
clean up transaction transmitter creation
dmitrii-ubskii Feb 23, 2023
775c438
clean up imports
dmitrii-ubskii Feb 23, 2023
49ae4bb
merged dependencies
dmitrii-ubskii Feb 23, 2023
0152f1d
query doesn't need to be clonable
dmitrii-ubskii Feb 23, 2023
77714c6
update IDE sync tool
dmitrii-ubskii Feb 23, 2023
caa1285
connection Debug
dmitrii-ubskii Feb 23, 2023
3a7139e
connection API change
dmitrii-ubskii Feb 24, 2023
71007f6
update dependencies
dmitrii-ubskii Feb 24, 2023
ffbb317
Err()? => return Err() in short circuit
dmitrii-ubskii Feb 24, 2023
9bd94e3
redundant clone
dmitrii-ubskii Feb 24, 2023
e039990
clippy
dmitrii-ubskii Feb 24, 2023
19bb2ea
options refactor
dmitrii-ubskii Feb 27, 2023
56f7db4
replace prints with logging
dmitrii-ubskii Feb 27, 2023
2745a0a
DatabaseManager doesn't need to be mut
dmitrii-ubskii Feb 28, 2023
bc91dad
rename permutation_tests => test_for_each_arg
dmitrii-ubskii Feb 28, 2023
7f8e0ea
rename test compatibility => runtimes
dmitrii-ubskii Mar 1, 2023
4692284
colon after TODO and FIXME
dmitrii-ubskii Mar 1, 2023
46096f5
reorder impls to put Debug/Display after inherent impl
dmitrii-ubskii Mar 1, 2023
5d02a7e
extraneous clone
dmitrii-ubskii Mar 1, 2023
6e9a491
databases does not need to be mutable
dmitrii-ubskii Mar 1, 2023
a30c52c
remove ref (old syntax)
dmitrii-ubskii Mar 1, 2023
9d9eb2e
block_on => run_blocking
dmitrii-ubskii Mar 1, 2023
d540766
pulse_shutdown_{sink,source}
dmitrii-ubskii Mar 1, 2023
72842fa
use tokio stream instead of our own
dmitrii-ubskii Mar 1, 2023
0cdb384
callback => response_sink
dmitrii-ubskii Mar 1, 2023
0a0db2b
reorder channel.rs
dmitrii-ubskii Mar 1, 2023
091da71
pull message into network, hide away protobuf
dmitrii-ubskii Mar 1, 2023
7e2ff1c
grpc_sink => request_sink, grpc_stream => response_source
dmitrii-ubskii Mar 1, 2023
eea1541
remove unused imports
dmitrii-ubskii Mar 1, 2023
d8f89c4
cache tls config
dmitrii-ubskii Mar 1, 2023
4385b43
proto/info => {common,database}
dmitrii-ubskii Mar 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .factory/automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ config:
version-candidate: VERSION
dependencies:
dependencies: [build]
typedb-common: [build]
typedb-protocol: [build, release]
typeql: [build, release]

build:
quality:
Expand Down Expand Up @@ -53,7 +55,7 @@ build:
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
bazel build //...
tools/start-core-server.sh
bazel test //tests:queries_core --test_arg=-- --test_arg=--test-threads=1 --test_output=streamed && export TEST_SUCCESS=0 || export TEST_SUCCESS=1
bazel test //tests:queries --test_arg=-- --test_arg=core --test_arg=--test-threads=1 --test_output=streamed && export TEST_SUCCESS=0 || export TEST_SUCCESS=1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query tests are now generated by a permutation macro for both core and cluster, so they are merged into a single test file and filtered at test time.

tools/stop-core-server.sh
exit $TEST_SUCCESS
test-integration-cluster:
Expand All @@ -65,9 +67,20 @@ build:
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
bazel build //...
source tools/start-cluster-servers.sh # use source to receive export vars
bazel test //tests:queries_cluster --test_env=ROOT_CA=$ROOT_CA --test_arg=-- --test_arg=--test-threads=1 --test_output=streamed && export TEST_SUCCESS=0 || export TEST_SUCCESS=1
bazel test //tests:queries --test_env=ROOT_CA=$ROOT_CA --test_arg=-- --test_arg=cluster --test_arg=--test-threads=1 --test_output=streamed && export TEST_SUCCESS=0 || export TEST_SUCCESS=1
tools/stop-cluster-servers.sh
exit $TEST_SUCCESS
test-integration-runtimes:
image: vaticle-ubuntu-22.04
command: |
export ARTIFACT_USERNAME=$REPO_VATICLE_USERNAME
export ARTIFACT_PASSWORD=$REPO_VATICLE_PASSWORD
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
bazel build //...
tools/start-core-server.sh
bazel test //tests:runtimes --test_arg=-- --test_arg=--test-threads=1 --test_output=streamed && export TEST_SUCCESS=0 || export TEST_SUCCESS=1
tools/stop-core-server.sh
exit $TEST_SUCCESS
deploy-crate-snapshot:
filter:
owner: vaticle
Expand Down
36 changes: 19 additions & 17 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,45 +31,47 @@ load("//:deployment.bzl", deployment_github = "deployment")
rust_library(
name = "typedb_client",
srcs = glob(["src/**/*.rs"]),
tags = ["crate-name=typedb-client"],
deps = [
"@crates//:chrono",
"@crates//:crossbeam",
"@crates//:futures",
"@crates//:http",
"@crates//:itertools",
"@crates//:log",
"@crates//:prost",
"@crates//:tokio",
"@crates//:tokio-stream",
"@crates//:tonic",
"@crates//:uuid",
"@vaticle_typedb_protocol//grpc/rust:typedb_protocol",
"@vaticle_typeql//rust:typeql_lang",

"@vaticle_dependencies//library/crates:chrono",
"@vaticle_dependencies//library/crates:crossbeam",
"@vaticle_dependencies//library/crates:futures",
"@vaticle_dependencies//library/crates:log",
"@vaticle_dependencies//library/crates:prost",
"@vaticle_dependencies//library/crates:tokio",
"@vaticle_dependencies//library/crates:tonic",
"@vaticle_dependencies//library/crates:uuid",
],
tags = ["crate-name=typedb-client"],
)

assemble_crate(
name = "assemble_crate",
target = "typedb_client",
description = "TypeDB Client API for Rust",
homepage = "https://github.com/vaticle/typedb-client-rust",
license = "Apache-2.0",
repository = "https://github.com/vaticle/typedb-client-rust",
target = "typedb_client",
)

deploy_crate(
name = "deploy_crate",
target = ":assemble_crate",
release = deployment["crate.release"],
snapshot = deployment["crate.snapshot"],
release = deployment["crate.release"]
target = ":assemble_crate",
)

deploy_github(
name = "deploy_github",
draft = True,
title = "TypeDB Client Rust",
release_description = "//:RELEASE_TEMPLATE.md",
organisation = deployment_github["github.organisation"],
release_description = "//:RELEASE_TEMPLATE.md",
repository = deployment_github["github.repository"],
title = "TypeDB Client Rust",
title_append_version = True,
)

Expand Down Expand Up @@ -105,13 +107,13 @@ filegroup(

rustfmt_test(
name = "client_rustfmt_test",
targets = ["typedb_client"]
targets = ["typedb_client"],
)

# CI targets that are not declared in any BUILD file, but are called externally
filegroup(
name = "ci",
data = [
"@vaticle_dependencies//ide/rust:sync"
"@vaticle_dependencies//tool/cargo:sync",
],
)
6 changes: 4 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_regi
rules_rust_dependencies()
rust_register_toolchains(edition = "2021", include_rustc_srcs = True)

load("@vaticle_dependencies//library/crates:crates.bzl", "raze_fetch_remote_crates")
raze_fetch_remote_crates()
load("@vaticle_dependencies//library/crates:crates.bzl", "fetch_crates")
fetch_crates()
load("@crates//:defs.bzl", "crate_repositories")
crate_repositories()

# Load //builder/python
load("@vaticle_dependencies//builder/python:deps.bzl", python_deps = "deps")
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion dependencies/ide/sync.sh → dependencies/ide/rust/sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
# under the License.
#

bazel run @vaticle_dependencies//ide/rust:sync
bazel run @vaticle_dependencies//tool/cargo:sync
8 changes: 4 additions & 4 deletions dependencies/vaticle/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,26 @@ def vaticle_dependencies():
git_repository(
name = "vaticle_dependencies",
remote = "https://github.com/vaticle/dependencies",
commit = "d76a7b935cd6452615f78772539fbc2e1228f503", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
commit = "76636b1672b04e9880439395b8913231724ae459", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
)

def vaticle_typedb_common():
git_repository(
name = "vaticle_typedb_common",
remote = "https://github.com/vaticle/typedb-common",
tag = "2.12.0" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
commit = "aa03cb5f6a57ec2a51291b7a0510734ca1f41479" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
)

def vaticle_typedb_protocol():
git_repository(
name = "vaticle_typedb_protocol",
remote = "https://github.com/vaticle/typedb-protocol",
commit = "16d1fb6749c0fee85843ca67f470015dda9fc497", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
commit = "b1c19e02054c1a1d354b42875e6ccd67602a546f", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
)

def vaticle_typeql():
git_repository(
name = "vaticle_typeql",
remote = "https://github.com/vaticle/typeql",
commit = "776643fb6f0c754730e55230733fd2326f32cd39", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
commit = "7a63699b3879296ae3039577ba3f5220bbf6d33d", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
)
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
use_small_heuristics = "Max"
max_width = 120
10 changes: 1 addition & 9 deletions src/answer/concept_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,14 @@ use std::{
ops::Index,
};

use crate::{common::Result, concept::Concept};
use crate::concept::Concept;

#[derive(Debug)]
pub struct ConceptMap {
pub map: HashMap<String, Concept>,
}

impl ConceptMap {
pub(crate) fn from_proto(proto: typedb_protocol::ConceptMap) -> Result<Self> {
let mut map = HashMap::with_capacity(proto.map.len());
for (k, v) in proto.map {
map.insert(k, Concept::from_proto(v)?);
}
Ok(Self { map })
}

Comment on lines -35 to -42
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to connection/network/proto.rs

pub fn get(&self, var_name: &str) -> Option<&Concept> {
self.map.get(var_name)
}
Expand Down
16 changes: 0 additions & 16 deletions src/answer/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
* under the License.
*/

use typedb_protocol::numeric::Value;

use crate::common::{Error, Result};

#[derive(Clone, Debug)]
pub enum Numeric {
Long(i64),
Expand All @@ -48,18 +44,6 @@ impl Numeric {
}
}

impl TryFrom<typedb_protocol::Numeric> for Numeric {
type Error = Error;

fn try_from(value: typedb_protocol::Numeric) -> Result<Self> {
match value.value.unwrap() {
Value::LongValue(long) => Ok(Numeric::Long(long)),
Value::DoubleValue(double) => Ok(Numeric::Double(double)),
Value::Nan(_) => Ok(Numeric::NaN),
}
}
}

impl From<Numeric> for i64 {
fn from(n: Numeric) -> Self {
n.into_i64()
Expand Down
6 changes: 3 additions & 3 deletions src/common/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

use std::{fmt, str::FromStr};

use tonic::transport::Uri;
use http::Uri;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use http directly, not tonic's re-exports.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good catch!


use crate::common::{Error, Result};

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Address {
pub(crate) struct Address {
uri: Uri,
}

Expand All @@ -43,7 +43,7 @@ impl FromStr for Address {
let uri = if address.contains("://") {
address.parse::<Uri>()?
} else {
format!("http://{}", address).parse::<Uri>()?
format!("http://{address}").parse::<Uri>()?
};
Ok(Self { uri })
}
Expand Down
83 changes: 24 additions & 59 deletions src/common/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,43 +19,42 @@
* under the License.
*/

use std::{
fs,
path::{Path, PathBuf},
sync::RwLock,
};
use std::{fmt, fs, path::Path};

use tonic::{
transport::{Certificate, ClientTlsConfig},
Request,
};
use tonic::transport::{Certificate, ClientTlsConfig};

use crate::Result;

#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct Credential {
username: String,
password: String,
is_tls_enabled: bool,
tls_root_ca: Option<PathBuf>,
tls_config: Option<ClientTlsConfig>,
}

impl Credential {
pub fn with_tls(username: &str, password: &str, tls_root_ca: Option<&Path>) -> Self {
Credential {
pub fn with_tls(username: &str, password: &str, tls_root_ca: Option<&Path>) -> Result<Self> {
let tls_config = Some(if let Some(tls_root_ca) = tls_root_ca {
ClientTlsConfig::new().ca_certificate(Certificate::from_pem(fs::read_to_string(tls_root_ca)?))
} else {
ClientTlsConfig::new()
});

Ok(Credential {
username: username.to_owned(),
password: password.to_owned(),
is_tls_enabled: true,
tls_root_ca: tls_root_ca.map(Path::to_owned),
}
tls_config,
})
}

pub fn without_tls(username: &str, password: &str) -> Self {
Credential {
username: username.to_owned(),
password: password.to_owned(),
is_tls_enabled: false,
tls_root_ca: None,
tls_config: None,
}
}

Expand All @@ -71,51 +70,17 @@ impl Credential {
self.is_tls_enabled
}

pub fn tls_config(&self) -> Result<ClientTlsConfig> {
if let Some(ref tls_root_ca) = self.tls_root_ca {
Ok(ClientTlsConfig::new()
.ca_certificate(Certificate::from_pem(fs::read_to_string(tls_root_ca)?)))
} else {
Ok(ClientTlsConfig::new())
}
pub fn tls_config(&self) -> &Option<ClientTlsConfig> {
&self.tls_config
}
}

#[derive(Debug)]
pub(crate) struct CallCredentials {
credential: Credential,
token: RwLock<Option<String>>,
}
Comment on lines -84 to -88
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved closer to channel.


impl CallCredentials {
pub(super) fn new(credential: Credential) -> Self {
Self { credential, token: RwLock::new(None) }
}

pub(super) fn username(&self) -> &str {
self.credential.username()
}

pub(super) fn password(&self) -> &str {
self.credential.password()
}

pub(super) fn set_token(&self, token: String) {
*self.token.write().unwrap() = Some(token);
}

pub(super) fn reset_token(&self) {
*self.token.write().unwrap() = None;
}

pub(super) fn inject(&self, mut request: Request<()>) -> Request<()> {
request.metadata_mut().insert("username", self.credential.username().try_into().unwrap());
match &*self.token.read().unwrap() {
Some(token) => request.metadata_mut().insert("token", token.try_into().unwrap()),
None => request
.metadata_mut()
.insert("password", self.credential.password().try_into().unwrap()),
};
request
impl fmt::Debug for Credential {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Credential")
.field("username", &self.username)
.field("is_tls_enabled", &self.is_tls_enabled)
.field("tls_config", &self.tls_config)
.finish()
}
}
Loading