You can definitely get around a lot of the pain points by using owned types like String as much as possible instead of borrowed types like &str. This is even generally recommended; there’s often no benefit to using the more advanced features of the language.
Usually the advanced features come in when you’re looking for better performance. It helps performance a lot to use reference types (borrowed types) to eliminate deep copies (and allocations) with .clone() in a loop, for example.
Library authors usually don’t have the luxury of knowing how their code will be used downstream, so diligent authors try to make the code reasonably performant and use these advanced language features to do so. You never know if the consumer of your library will use your function in a hot loop.
Usually the advanced features come in when you’re looking for better performance. It helps performance a lot to use reference types (borrowed types) to eliminate deep copies (and allocations) with .clone() in a loop, for example.
Library authors usually don’t have the luxury of knowing how their code will be used downstream, so diligent authors try to make the code reasonably performant and use these advanced language features to do so. You never know if the consumer of your library will use your function in a hot loop.