Debloat the binary by using less AsRef arguments

Using `impl AsRef<str>` as the argument instead of `&str` makes it
possible to call the function with `&str`, `String` and other types
that implement `AsRef` trait.

The cost of it is that compiled binary contains mulitple versions of
the same function, one for each variant of types. If function contains
multiple generic `impl AsRef` arguments, the number of versions possibly
compiled into binary grows exponentially with the number of arguments.

Simple way to avoid it is to call `.as_ref()` on the caller side to
convert the argument to `&str`. In most cases even adding a `&` and
relying on `Deref` coercion is sufficient.

This patch changes many functions that accepted `impl AsRef<str>` and
`impl AsRef<Path>` to accept `&str` and `&Path` instead.

In some places `.clone()` calls are removed. Calling `.clone()` on
`String` and passing `String` to a function accepting `impl
AsRef<str>` is completely unnecessary as `&str` reference could be
passed instead. There is no clippy warning against it yet, but
changing argument type to `&str` allowed to find these cases.

The result of debloating is not impressive, several hundred kilobytes
are saved, which is about 3% of the `.so` binary, but the code is
cleaner too.
This commit is contained in:
link2xt
2021-05-08 16:52:29 +03:00
parent 03f0659454
commit adac903818
29 changed files with 244 additions and 308 deletions

View File

@@ -1367,7 +1367,7 @@ pub(crate) async fn update_saved_messages_icon(context: &Context) -> Result<()>
// if there is no saved-messages chat, there is nothing to update. this is no error.
if let Some(chat_id) = ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF).await? {
let icon = include_bytes!("../assets/icon-saved-messages.png");
let blob = BlobObject::create(context, "icon-saved-messages.png".to_string(), icon).await?;
let blob = BlobObject::create(context, "icon-saved-messages.png", icon).await?;
let icon = blob.as_name().to_string();
let mut chat = Chat::load_from_db(context, chat_id).await?;
@@ -1381,7 +1381,7 @@ pub(crate) async fn update_device_icon(context: &Context) -> Result<()> {
// if there is no device-chat, there is nothing to update. this is no error.
if let Some(chat_id) = ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE).await? {
let icon = include_bytes!("../assets/icon-device.png");
let blob = BlobObject::create(context, "icon-device.png".to_string(), icon).await?;
let blob = BlobObject::create(context, "icon-device.png", icon).await?;
let icon = blob.as_name().to_string();
let mut chat = Chat::load_from_db(context, chat_id).await?;
@@ -2174,7 +2174,7 @@ pub async fn get_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec
pub async fn create_group_chat(
context: &Context,
protect: ProtectionStatus,
chat_name: impl AsRef<str>,
chat_name: &str,
) -> Result<ChatId> {
let chat_name = improve_single_line_input(chat_name);
ensure!(!chat_name.is_empty(), "Invalid chat name");
@@ -2531,7 +2531,7 @@ pub async fn remove_contact_from_chat(
if chat.is_promoted() {
msg.viewtype = Viewtype::Text;
if contact.id == DC_CONTACT_ID_SELF {
set_group_explicitly_left(context, chat.grpid).await?;
set_group_explicitly_left(context, &chat.grpid).await?;
msg.text = Some(
stock_str::msg_group_left(context, DC_CONTACT_ID_SELF as u32).await,
);
@@ -2573,13 +2573,13 @@ pub async fn remove_contact_from_chat(
Ok(())
}
async fn set_group_explicitly_left(context: &Context, grpid: impl AsRef<str>) -> Result<()> {
if !is_group_explicitly_left(context, grpid.as_ref()).await? {
async fn set_group_explicitly_left(context: &Context, grpid: &str) -> Result<()> {
if !is_group_explicitly_left(context, grpid).await? {
context
.sql
.execute(
"INSERT INTO leftgrps (grpid) VALUES(?);",
paramsv![grpid.as_ref().to_string()],
paramsv![grpid.to_string()],
)
.await?;
}
@@ -2601,11 +2601,7 @@ pub(crate) async fn is_group_explicitly_left(
Ok(exists)
}
pub async fn set_chat_name(
context: &Context,
chat_id: ChatId,
new_name: impl AsRef<str>,
) -> Result<()> {
pub async fn set_chat_name(context: &Context, chat_id: ChatId, new_name: &str) -> Result<()> {
let new_name = improve_single_line_input(new_name);
/* the function only sets the names of group chats; normal chats get their names from the contacts */
let mut success = false;