cargo fmt

This commit is contained in:
Martin Dahl 2021-08-17 13:22:20 +02:00
parent ac51828cad
commit 42bf5d9906
13 changed files with 111 additions and 103 deletions

View File

@ -21,7 +21,8 @@ async fn requester_task(c: r2r::UntypedClient) -> Result<(), Box<dyn std::error:
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let ctx = r2r::Context::create()?; let ctx = r2r::Context::create()?;
let mut node = r2r::Node::create(ctx, "testnode", "")?; let mut node = r2r::Node::create(ctx, "testnode", "")?;
let client = node.create_client_untyped("/add_two_ints", "example_interfaces/srv/AddTwoInts")?; let client =
node.create_client_untyped("/add_two_ints", "example_interfaces/srv/AddTwoInts")?;
// wait for service to be available // wait for service to be available
println!("waiting for service..."); println!("waiting for service...");

View File

@ -140,10 +140,10 @@ macro_rules! primitive_sequence {
primitive_sequence!(rosidl_runtime_c__float32, f32); primitive_sequence!(rosidl_runtime_c__float32, f32);
primitive_sequence!(rosidl_runtime_c__float64, f64); primitive_sequence!(rosidl_runtime_c__float64, f64);
#[cfg(all(target_os="macos", target_arch = "aarch64"))] #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
primitive_sequence!(rosidl_runtime_c__long_double, f64); primitive_sequence!(rosidl_runtime_c__long_double, f64);
#[cfg(not(all(target_os="macos", target_arch = "aarch64")))] #[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
primitive_sequence!(rosidl_runtime_c__long_double, u128); primitive_sequence!(rosidl_runtime_c__long_double, u128);
primitive_sequence!(rosidl_runtime_c__char, i8); primitive_sequence!(rosidl_runtime_c__char, i8);

View File

@ -53,12 +53,14 @@ where
&self, &self,
goal: T::Goal, goal: T::Goal,
) -> Result< ) -> Result<
impl Future<Output = Result< impl Future<
( Output = Result<(
ClientGoal<T>, ClientGoal<T>,
impl Future<Output = Result<(GoalStatus, T::Result)>>, impl Future<Output = Result<(GoalStatus, T::Result)>>,
impl Stream<Item = T::Feedback> + Unpin, impl Stream<Item = T::Feedback> + Unpin,
)>>> )>,
>,
>
where where
T: WrappedActionTypeSupport, T: WrappedActionTypeSupport,
{ {
@ -112,12 +114,14 @@ where
c.send_result_request(uuid.clone()); c.send_result_request(uuid.clone());
} }
Ok((ClientGoal { Ok((
client: fut_client, ClientGoal {
uuid, client: fut_client,
}, result_receiver uuid,
.map_err(|_| Error::RCL_RET_ACTION_CLIENT_INVALID), },
feedback_receiver)) result_receiver.map_err(|_| Error::RCL_RET_ACTION_CLIENT_INVALID),
feedback_receiver,
))
} else { } else {
println!("goal rejected"); println!("goal rejected");
Err(Error::RCL_RET_ACTION_GOAL_REJECTED) Err(Error::RCL_RET_ACTION_GOAL_REJECTED)
@ -137,9 +141,7 @@ pub fn make_action_client<T>(client: Weak<Mutex<WrappedActionClient<T>>>) -> Act
where where
T: WrappedActionTypeSupport, T: WrappedActionTypeSupport,
{ {
ActionClient { ActionClient { client }
client
}
} }
pub fn action_server_available<T>(node: &rcl_node_t, client: &ActionClient<T>) -> Result<bool> pub fn action_server_available<T>(node: &rcl_node_t, client: &ActionClient<T>) -> Result<bool>
@ -152,9 +154,7 @@ where
.ok_or(Error::RCL_RET_CLIENT_INVALID)?; .ok_or(Error::RCL_RET_CLIENT_INVALID)?;
let client = client.lock().unwrap(); let client = client.lock().unwrap();
let mut avail = false; let mut avail = false;
let result = unsafe { let result = unsafe { rcl_action_server_is_available(node, client.handle(), &mut avail) };
rcl_action_server_is_available(node, client.handle(), &mut avail)
};
if result == RCL_RET_OK as i32 { if result == RCL_RET_OK as i32 {
Ok(avail) Ok(avail)
@ -230,7 +230,8 @@ where
<<T as WrappedActionTypeSupport>::SendGoal as WrappedServiceTypeSupport>::Response, <<T as WrappedActionTypeSupport>::SendGoal as WrappedServiceTypeSupport>::Response,
>, >,
)>, )>,
pub cancel_response_channels: Vec<(i64, oneshot::Sender<action_msgs::srv::CancelGoal::Response>)>, pub cancel_response_channels:
Vec<(i64, oneshot::Sender<action_msgs::srv::CancelGoal::Response>)>,
pub feedback_senders: Vec<(uuid::Uuid, mpsc::Sender<T::Feedback>)>, pub feedback_senders: Vec<(uuid::Uuid, mpsc::Sender<T::Feedback>)>,
pub result_requests: Vec<(i64, uuid::Uuid)>, pub result_requests: Vec<(i64, uuid::Uuid)>,
pub result_senders: Vec<(uuid::Uuid, oneshot::Sender<(GoalStatus, T::Result)>)>, pub result_senders: Vec<(uuid::Uuid, oneshot::Sender<(GoalStatus, T::Result)>)>,
@ -265,7 +266,10 @@ where
*self.goal_status.get(uuid).unwrap_or(&GoalStatus::Unknown) *self.goal_status.get(uuid).unwrap_or(&GoalStatus::Unknown)
} }
pub fn send_cancel_request(&mut self, goal: &uuid::Uuid) -> Result<impl Future<Output = Result<()>>> pub fn send_cancel_request(
&mut self,
goal: &uuid::Uuid,
) -> Result<impl Future<Output = Result<()>>>
where where
T: WrappedActionTypeSupport, T: WrappedActionTypeSupport,
{ {

View File

@ -18,29 +18,23 @@ where
T: WrappedServiceTypeSupport, T: WrappedServiceTypeSupport,
{ {
// upgrade to actual ref. if still alive // upgrade to actual ref. if still alive
let client = self let client = self.client.upgrade().ok_or(Error::RCL_RET_CLIENT_INVALID)?;
.client
.upgrade()
.ok_or(Error::RCL_RET_CLIENT_INVALID)?;
let mut client = client.lock().unwrap(); let mut client = client.lock().unwrap();
client.request(msg) client.request(msg)
} }
} }
pub struct UntypedClient pub struct UntypedClient {
{
client: Weak<Mutex<UntypedClient_>>, client: Weak<Mutex<UntypedClient_>>,
} }
impl UntypedClient impl UntypedClient {
{ pub fn request(
pub fn request(&self, msg: serde_json::Value) -> Result<impl Future<Output = Result<Result<serde_json::Value>>>> &self,
{ msg: serde_json::Value,
) -> Result<impl Future<Output = Result<Result<serde_json::Value>>>> {
// upgrade to actual ref. if still alive // upgrade to actual ref. if still alive
let client = self let client = self.client.upgrade().ok_or(Error::RCL_RET_CLIENT_INVALID)?;
.client
.upgrade()
.ok_or(Error::RCL_RET_CLIENT_INVALID)?;
let mut client = client.lock().unwrap(); let mut client = client.lock().unwrap();
client.request(msg) client.request(msg)
} }
@ -50,15 +44,11 @@ pub fn make_client<T>(client: Weak<Mutex<TypedClient<T>>>) -> Client<T>
where where
T: WrappedServiceTypeSupport, T: WrappedServiceTypeSupport,
{ {
Client { Client { client }
client
}
} }
pub fn make_untyped_client(client: Weak<Mutex<UntypedClient_>>) -> UntypedClient { pub fn make_untyped_client(client: Weak<Mutex<UntypedClient_>>) -> UntypedClient {
UntypedClient { UntypedClient { client }
client
}
} }
unsafe impl<T> Send for TypedClient<T> where T: WrappedServiceTypeSupport {} unsafe impl<T> Send for TypedClient<T> where T: WrappedServiceTypeSupport {}
@ -92,8 +82,10 @@ where
unsafe impl Send for UntypedClient_ {} unsafe impl Send for UntypedClient_ {}
impl UntypedClient_ { impl UntypedClient_ {
pub fn request(&mut self, msg: serde_json::Value) -> Result<impl Future<Output = Result<Result<serde_json::Value>>>> pub fn request(
{ &mut self,
msg: serde_json::Value,
) -> Result<impl Future<Output = Result<Result<serde_json::Value>>>> {
let mut native_msg = (self.service_type.make_request_msg)(); let mut native_msg = (self.service_type.make_request_msg)();
native_msg.from_json(msg)?; native_msg.from_json(msg)?;
@ -184,15 +176,13 @@ where
} }
} }
pub struct UntypedClient_ pub struct UntypedClient_ {
{
pub service_type: UntypedServiceSupport, pub service_type: UntypedServiceSupport,
pub rcl_handle: rcl_client_t, pub rcl_handle: rcl_client_t,
pub response_channels: Vec<(i64, oneshot::Sender<Result<serde_json::Value>>)>, pub response_channels: Vec<(i64, oneshot::Sender<Result<serde_json::Value>>)>,
} }
impl Client_ for UntypedClient_ impl Client_ for UntypedClient_ {
{
fn handle(&self) -> &rcl_client_t { fn handle(&self) -> &rcl_client_t {
&self.rcl_handle &self.rcl_handle
} }
@ -273,9 +263,7 @@ pub fn create_client_helper(
pub fn service_available_helper(node: &mut rcl_node_t, client: &rcl_client_t) -> Result<bool> { pub fn service_available_helper(node: &mut rcl_node_t, client: &rcl_client_t) -> Result<bool> {
let mut avail = false; let mut avail = false;
let result = unsafe { let result = unsafe { rcl_service_server_is_available(node, client, &mut avail) };
rcl_service_server_is_available(node, client, &mut avail)
};
if result == RCL_RET_OK as i32 { if result == RCL_RET_OK as i32 {
Ok(avail) Ok(avail)
@ -284,7 +272,10 @@ pub fn service_available_helper(node: &mut rcl_node_t, client: &rcl_client_t) ->
} }
} }
pub fn service_available<T: 'static + WrappedServiceTypeSupport>(node: &mut rcl_node_t, client: &Client<T>) -> Result<bool> { pub fn service_available<T: 'static + WrappedServiceTypeSupport>(
node: &mut rcl_node_t,
client: &Client<T>,
) -> Result<bool> {
let client = client let client = client
.client .client
.upgrade() .upgrade()

View File

@ -21,7 +21,6 @@ pub fn clock_type_to_rcl(ct: &ClockType) -> rcl_clock_type_t {
} }
} }
impl Clock { impl Clock {
pub fn create(ct: ClockType) -> Result<Clock> { pub fn create(ct: ClockType) -> Result<Clock> {
let mut clock_handle = MaybeUninit::<rcl_clock_t>::uninit(); let mut clock_handle = MaybeUninit::<rcl_clock_t>::uninit();

View File

@ -1,6 +1,5 @@
use super::*; use super::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Context { pub struct Context {
pub context_handle: Arc<Mutex<ContextHandle>>, pub context_handle: Arc<Mutex<ContextHandle>>,

View File

@ -23,7 +23,7 @@ use actions::*;
use rcl::*; use rcl::*;
mod error; mod error;
use error::*; pub use error::{Error, Result};
mod msg_types; mod msg_types;
use msg_types::*; use msg_types::*;
@ -39,8 +39,10 @@ use subscribers::*;
mod publishers; mod publishers;
use publishers::*; use publishers::*;
pub use publishers::{Publisher, PublisherUntyped};
mod services; mod services;
pub use services::ServiceRequest;
use services::*; use services::*;
mod clients; mod clients;
@ -48,18 +50,19 @@ use clients::*;
pub use clients::{Client, UntypedClient}; pub use clients::{Client, UntypedClient};
mod action_clients; mod action_clients;
pub use action_clients::ActionClient;
use action_clients::*; use action_clients::*;
mod action_servers; mod action_servers;
use action_servers::*; use action_servers::*;
pub use action_servers::{ActionServer, GoalRequest, ServerGoal, CancelRequest}; pub use action_servers::{ActionServer, CancelRequest, GoalRequest, ServerGoal};
mod context; mod context;
pub use context::Context; pub use context::Context;
mod parameters; mod parameters;
use parameters::*;
pub use parameters::ParameterValue; pub use parameters::ParameterValue;
use parameters::*;
mod clocks; mod clocks;
pub use clocks::{Clock, ClockType}; pub use clocks::{Clock, ClockType};

View File

@ -127,12 +127,8 @@ impl UntypedServiceSupport {
where where
T: WrappedServiceTypeSupport, T: WrappedServiceTypeSupport,
{ {
let make_request_msg = || { let make_request_msg = || WrappedNativeMsgUntyped::new::<T::Request>();
WrappedNativeMsgUntyped::new::<T::Request>() let make_response_msg = || WrappedNativeMsgUntyped::new::<T::Response>();
};
let make_response_msg = || {
WrappedNativeMsgUntyped::new::<T::Response>()
};
UntypedServiceSupport { UntypedServiceSupport {
ts: T::get_ts(), ts: T::get_ts(),

View File

@ -162,7 +162,8 @@ impl Node {
where where
T: WrappedTypesupport, T: WrappedTypesupport,
{ {
let subscription_handle = create_subscription_helper(self.node_handle.as_mut(), topic, T::get_ts())?; let subscription_handle =
create_subscription_helper(self.node_handle.as_mut(), topic, T::get_ts())?;
let (sender, receiver) = mpsc::channel::<T>(10); let (sender, receiver) = mpsc::channel::<T>(10);
let ws = TypedSubscriber { let ws = TypedSubscriber {
@ -180,7 +181,8 @@ impl Node {
where where
T: WrappedTypesupport, T: WrappedTypesupport,
{ {
let subscription_handle = create_subscription_helper(self.node_handle.as_mut(), topic, T::get_ts())?; let subscription_handle =
create_subscription_helper(self.node_handle.as_mut(), topic, T::get_ts())?;
let (sender, receiver) = mpsc::channel::<WrappedNativeMsg<T>>(10); let (sender, receiver) = mpsc::channel::<WrappedNativeMsg<T>>(10);
let ws = NativeSubscriber { let ws = NativeSubscriber {
@ -198,7 +200,8 @@ impl Node {
topic_type: &str, topic_type: &str,
) -> Result<impl Stream<Item = Result<serde_json::Value>> + Unpin> { ) -> Result<impl Stream<Item = Result<serde_json::Value>> + Unpin> {
let msg = WrappedNativeMsgUntyped::new_from(topic_type)?; let msg = WrappedNativeMsgUntyped::new_from(topic_type)?;
let subscription_handle = create_subscription_helper(self.node_handle.as_mut(), topic, msg.ts)?; let subscription_handle =
create_subscription_helper(self.node_handle.as_mut(), topic, msg.ts)?;
let (sender, receiver) = mpsc::channel::<Result<serde_json::Value>>(10); let (sender, receiver) = mpsc::channel::<Result<serde_json::Value>>(10);
let ws = UntypedSubscriber { let ws = UntypedSubscriber {
@ -217,7 +220,8 @@ impl Node {
where where
T: WrappedServiceTypeSupport, T: WrappedServiceTypeSupport,
{ {
let service_handle = create_service_helper(self.node_handle.as_mut(), service_name, T::get_ts())?; let service_handle =
create_service_helper(self.node_handle.as_mut(), service_name, T::get_ts())?;
let (sender, receiver) = mpsc::channel::<ServiceRequest<T>>(10); let (sender, receiver) = mpsc::channel::<ServiceRequest<T>>(10);
let ws = TypedService::<T> { let ws = TypedService::<T> {
@ -234,7 +238,8 @@ impl Node {
where where
T: WrappedServiceTypeSupport, T: WrappedServiceTypeSupport,
{ {
let client_handle = create_client_helper(self.node_handle.as_mut(), service_name, T::get_ts())?; let client_handle =
create_client_helper(self.node_handle.as_mut(), service_name, T::get_ts())?;
let ws = TypedClient::<T> { let ws = TypedClient::<T> {
rcl_handle: client_handle, rcl_handle: client_handle,
response_channels: Vec::new(), response_channels: Vec::new(),
@ -247,10 +252,14 @@ impl Node {
} }
/// Create a service client without having the concrete rust type. /// Create a service client without having the concrete rust type.
pub fn create_client_untyped(&mut self, service_name: &str, service_type: &str) -> Result<UntypedClient> pub fn create_client_untyped(
{ &mut self,
service_name: &str,
service_type: &str,
) -> Result<UntypedClient> {
let service_type = UntypedServiceSupport::new_from(service_type)?; let service_type = UntypedServiceSupport::new_from(service_type)?;
let client_handle = create_client_helper(self.node_handle.as_mut(), service_name, service_type.ts)?; let client_handle =
create_client_helper(self.node_handle.as_mut(), service_name, service_type.ts)?;
let client = UntypedClient_ { let client = UntypedClient_ {
service_type, service_type,
rcl_handle: client_handle, rcl_handle: client_handle,
@ -263,7 +272,10 @@ impl Node {
Ok(c) Ok(c)
} }
pub fn service_available<T: 'static + WrappedServiceTypeSupport>(&mut self, client: &Client<T>) -> Result<bool> { pub fn service_available<T: 'static + WrappedServiceTypeSupport>(
&mut self,
client: &Client<T>,
) -> Result<bool> {
service_available(self.node_handle.as_mut(), client) service_available(self.node_handle.as_mut(), client)
} }
@ -275,7 +287,8 @@ impl Node {
where where
T: WrappedActionTypeSupport, T: WrappedActionTypeSupport,
{ {
let client_handle = create_action_client_helper(self.node_handle.as_mut(), action_name, T::get_ts())?; let client_handle =
create_action_client_helper(self.node_handle.as_mut(), action_name, T::get_ts())?;
let client = WrappedActionClient::<T> { let client = WrappedActionClient::<T> {
rcl_handle: client_handle, rcl_handle: client_handle,
goal_response_channels: Vec::new(), goal_response_channels: Vec::new(),
@ -322,8 +335,12 @@ impl Node {
let (goal_request_sender, goal_request_receiver) = mpsc::channel::<GoalRequest<T>>(10); let (goal_request_sender, goal_request_receiver) = mpsc::channel::<GoalRequest<T>>(10);
let server_handle = let server_handle = create_action_server_helper(
create_action_server_helper(self.node_handle.as_mut(), action_name, clock_handle.as_mut(), T::get_ts())?; self.node_handle.as_mut(),
action_name,
clock_handle.as_mut(),
T::get_ts(),
)?;
let server = WrappedActionServer::<T> { let server = WrappedActionServer::<T> {
rcl_handle: server_handle, rcl_handle: server_handle,
clock_handle, clock_handle,
@ -344,7 +361,8 @@ impl Node {
where where
T: WrappedTypesupport, T: WrappedTypesupport,
{ {
let publisher_handle = create_publisher_helper(self.node_handle.as_mut(), topic, T::get_ts())?; let publisher_handle =
create_publisher_helper(self.node_handle.as_mut(), topic, T::get_ts())?;
let arc = Arc::new(publisher_handle); let arc = Arc::new(publisher_handle);
let p = make_publisher(Arc::downgrade(&arc)); let p = make_publisher(Arc::downgrade(&arc));
self.pubs.push(arc); self.pubs.push(arc);
@ -501,7 +519,11 @@ impl Node {
} }
for acs in &self.action_servers { for acs in &self.action_servers {
unsafe { unsafe {
rcl_action_wait_set_add_action_server(&mut ws, acs.lock().unwrap().handle(), std::ptr::null_mut()); rcl_action_wait_set_add_action_server(
&mut ws,
acs.lock().unwrap().handle(),
std::ptr::null_mut(),
);
} }
} }

View File

@ -45,18 +45,12 @@ pub fn parameter_value_from_rcl(v: &rcl_variant_t) -> ParameterValue {
ParameterValue::IntegerArray(vals.iter().cloned().collect()) ParameterValue::IntegerArray(vals.iter().cloned().collect())
} else if v.double_array_value != std::ptr::null_mut() { } else if v.double_array_value != std::ptr::null_mut() {
let vals = unsafe { let vals = unsafe {
std::slice::from_raw_parts( std::slice::from_raw_parts((*v.double_array_value).values, (*v.double_array_value).size)
(*v.double_array_value).values,
(*v.double_array_value).size,
)
}; };
ParameterValue::DoubleArray(vals.iter().cloned().collect()) ParameterValue::DoubleArray(vals.iter().cloned().collect())
} else if v.string_array_value != std::ptr::null_mut() { } else if v.string_array_value != std::ptr::null_mut() {
let vals = unsafe { let vals = unsafe {
std::slice::from_raw_parts( std::slice::from_raw_parts((*v.string_array_value).data, (*v.string_array_value).size)
(*v.string_array_value).data,
(*v.string_array_value).size,
)
}; };
let s = vals let s = vals
.iter() .iter()

View File

@ -44,7 +44,9 @@ pub struct PublisherUntyped {
} }
pub fn make_publisher<T>(handle: Weak<rcl_publisher_t>) -> Publisher<T> pub fn make_publisher<T>(handle: Weak<rcl_publisher_t>) -> Publisher<T>
where T: WrappedTypesupport { where
T: WrappedTypesupport,
{
Publisher { Publisher {
handle, handle,
type_: PhantomData, type_: PhantomData,
@ -52,10 +54,7 @@ where T: WrappedTypesupport {
} }
pub fn make_publisher_untyped(handle: Weak<rcl_publisher_t>, type_: String) -> PublisherUntyped { pub fn make_publisher_untyped(handle: Weak<rcl_publisher_t>, type_: String) -> PublisherUntyped {
PublisherUntyped { PublisherUntyped { handle, type_ }
handle,
type_,
}
} }
pub fn create_publisher_helper( pub fn create_publisher_helper(
@ -84,7 +83,6 @@ pub fn create_publisher_helper(
} }
} }
impl PublisherUntyped { impl PublisherUntyped {
pub fn publish(&self, msg: serde_json::Value) -> Result<()> { pub fn publish(&self, msg: serde_json::Value) -> Result<()> {
// upgrade to actual ref. if still alive // upgrade to actual ref. if still alive

View File

@ -18,7 +18,10 @@ where
{ {
/// Complete the service request, consuming the request in the process. /// Complete the service request, consuming the request in the process.
pub fn respond(self, msg: T::Response) -> Result<()> { pub fn respond(self, msg: T::Response) -> Result<()> {
let service = self.service.upgrade().ok_or(Error::RCL_RET_ACTION_SERVER_INVALID)?; let service = self
.service
.upgrade()
.ok_or(Error::RCL_RET_ACTION_SERVER_INVALID)?;
let mut service = service.lock().unwrap(); let mut service = service.lock().unwrap();
let native_msg = WrappedNativeMsg::<T::Response>::from(&msg); let native_msg = WrappedNativeMsg::<T::Response>::from(&msg);
service.send_response(self.request_id, Box::new(native_msg)) service.send_response(self.request_id, Box::new(native_msg))
@ -49,14 +52,13 @@ where
&self.rcl_handle &self.rcl_handle
} }
fn send_response(&mut self, mut request_id: rmw_request_id_t, mut msg: Box<dyn VoidPtr>) -> Result<()> { fn send_response(
let res = unsafe { &mut self,
rcl_send_response( mut request_id: rmw_request_id_t,
&self.rcl_handle, mut msg: Box<dyn VoidPtr>,
&mut request_id, ) -> Result<()> {
msg.void_ptr_mut(), let res =
) unsafe { rcl_send_response(&self.rcl_handle, &mut request_id, msg.void_ptr_mut()) };
};
if res == RCL_RET_OK as i32 { if res == RCL_RET_OK as i32 {
Ok(()) Ok(())
} else { } else {
@ -81,7 +83,7 @@ where
let request = ServiceRequest::<T> { let request = ServiceRequest::<T> {
message: request_msg, message: request_msg,
request_id, request_id,
service: Arc::downgrade(&service) service: Arc::downgrade(&service),
}; };
match self.sender.try_send(request) { match self.sender.try_send(request) {
Err(e) => eprintln!("warning: could not send service request ({})", e), Err(e) => eprintln!("warning: could not send service request ({})", e),

View File

@ -130,7 +130,6 @@ impl Subscriber_ for UntypedSubscriber {
} }
} }
pub fn create_subscription_helper( pub fn create_subscription_helper(
node: &mut rcl_node_t, node: &mut rcl_node_t,
topic: &str, topic: &str,