{"id":1025,"date":"2022-12-02T13:55:50","date_gmt":"2022-12-02T13:55:50","guid":{"rendered":"https:\/\/infobip.com\/developers\/?p=1025"},"modified":"2023-09-11T14:32:38","modified_gmt":"2023-09-11T14:32:38","slug":"what-makes-a-good-rust-library","status":"publish","type":"post","link":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library","title":{"rendered":"What makes a good Rust library?"},"content":{"rendered":"\n<p>You might have heard of Rust, the shiny, fancy, safe, and fast language everybody is talking about nowadays. If not, you might want to check how <a href=\"https:\/\/infobip.com\/developers\/blog\/how-rust-provides-a-better-developer-experience-and-safer-and-faster-software\/\">Rust gives you a better developer experience<\/a><\/p>\n\n\n\n<p>Being a fairly recent language, it needs more high-quality libraries to enable\nmore people to use it for different use cases. At Infobip, we have just created\nthe <a href=\"https:\/\/crates.io\/crates\/infobip_sdk\"><code>infobip-api-rust-sdk<\/code><\/a>, which gives\nyou access to communication channels, like SMS, WhatsApp, and Email. If you\never wanted to create a crate, as they are called in Rust, you might have\nwondered how to create one and what should go into a library so that it&#8217;s\ngreat.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-library-fulfills-its-purpose\">The library fulfills its purpose<\/h2>\n\n\n\n<p>The crucial feature that makes a library good is when it serves its main\npurpose, helping developers save time. How to achieve it? Your library should\nbe great in the following aspects:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Easy to use<\/li>\n\n\n\n<li>Well organized<\/li>\n\n\n\n<li>Idiomatic<\/li>\n\n\n\n<li>Complete<\/li>\n\n\n\n<li>Fast<\/li>\n\n\n\n<li>Easy to develop and maintain<\/li>\n\n\n\n<li>Well documented<\/li>\n\n\n\n<li>Compliant with established conventions<\/li>\n\n\n\n<li>Hosted in a healthy repository<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"467\" src=\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\" alt=\"\" class=\"wp-image-1027\" srcset=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png 1024w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-300x137.png 300w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-768x350.png 768w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1536x700.png 1536w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-2048x933.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now, I will elaborate on how we achieved these items using our Infobip SDK an example.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"it-saves-time\">It saves time<\/h3>\n\n\n\n<p>The main aspect that makes a library useful is that it removes the hassle of having to do things by yourself. In the case of communicating with an HTTP API with pure Rust, you would have to do many things like finding a good HTTP client and creating abstractions for endpoints, payloads, and responses. Additionally, you would have to find a good structure for this boilerplate code in your project and be in charge of updates. We, at Infobip, wanted to make this much easier by providing a simple package that includes all these things, and more! <\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"475\" data-id=\"1028\" src=\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-1024x475.png\" alt=\"\" class=\"wp-image-1028\" srcset=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-1024x475.png 1024w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-300x139.png 300w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-768x357.png 768w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-1536x713.png 1536w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-2048x951.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-easy-to-use\">It&#8217;s easy to use<\/h3>\n\n\n\n<p>To make it easy to use, we included abstractions to configure the client\nlibrary and shortened names for the endpoint functions. We also tried to be\nshort, semantically correct, and consistent with payload and response naming.<\/p>\n\n\n\n<p>The following is an example of how to send an SMS message with the SDK:<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-rust\" data-lang=\"Rust\"><code>let sms_client = SmsClient::with_configuration(Configuration::from_env_api_key()?);\n\nlet mut message = Message::new(vec[Destination::new(&quot;555555555555&quot;.to_string())]);\nmessage.text = Some(&quot;Hello Rustacean!&quot;.to_string());\n\nlet request_body = SendRequestBody::new(vec![message]);\n\nlet response = sms_client.send(request_body).await?;<\/code><\/pre><\/div>\n\n\n\n<p>It&#8217;s only a few lines. The first one is to create an SMS client instance with a\nconfiguration loaded from environment variables that include a specific URL and\nAPI Key. The second line creates a message instance that includes a list of\ndestination numbers, which in this case, contains one. Then, we set the desired \ntext of the message. Next, We create a request body that contains the previously\ncreated message. Finally, we call the <code>sms_client.send()<\/code> function and receive\na response. Our message is sent!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-neatly-organized\">It&#8217;s neatly organized<\/h3>\n\n\n\n<p>A library that has a logical organization, makes it easier to find things\ninside it. In Rust, that is also beneficial because you can use a feature of\nCargo called Features, which allows you to reduce the amount of code that needs\nto be compiled. This is especially useful in Rust because the compiler does\nmore work than in other languages, and it takes longer to compile.<\/p>\n\n\n\n<p>To only compile the features that you need (may it be one or more), use a line\nlike the following in your Cargo.toml file:<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-rust\" data-lang=\"Rust\"><code>infobip_sdk = { version = &quot;0.3&quot;, features = [ &quot;sms&quot; ] }<\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-fast\">It&#8217;s fast<\/h3>\n\n\n\n<p>To enable you to write performant applications, we made the library\nasynchronous. This means that you can perform several IO operations in\nparallel, and even do other things at the same time. That might save huge time\nwhen you have a lot of calls to a network or storage device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-well-documented\">It&#8217;s well documented<\/h3>\n\n\n\n<p>To make a library successful, instructions on how to use it should be readily\navailable. For this, we used the standard way of documenting an SDK library,\nwhich is the Cargo documentation system, and Docs.rs, the online documentation\nplatform where Rust crates are usually uploaded.<\/p>\n\n\n\n<p>For every endpoint, you can find a comprehensive description. It also includes the\nsignature of the function, that is, what parameters it has and what it\nreturns. Additionally, we provided code examples for every endpoint. This is\nespecially cool in Rust, because those examples in documentation can be\nactually compiled and run, so we make sure that when we introduce more changes\nto the library, the code still works release after release.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-easy-to-develop\">It&#8217;s easy to develop<\/h3>\n\n\n\n<p>To keep a library improving and updating, it must be as simple and easy to\ndevelop as possible. Automation helps a lot in achieving this. We are using the\npower of the OpenAPI specification and OpenAPI Generator. We generated code and\nfrom that, we picked what was most useful. That saved a lot of time with\ndocumentation generation and modelling of the API objects. Once created, models\nhave been improved for better naming conventions and additional features. One\nexample is the name of the endpoint for sending SMS, which comes generated as\n<code>send_fully_feauterd_textual_message<\/code>, and becomes <code>sms_client.send()<\/code>. After\ngenerating models we implemented custom logic for endpoints. We improved error\nhandling, and redesigned the module structure. All of the above has created a\nsolid code base that is fast to grow and enhance. Even tools like GitHub\ncopilot play well with the code base, removing the need to type a lot of the\nboilerplate that comes in repetitive parts of the library.<\/p>\n\n\n\n<p>The easier the library is to develop, the most likely it will grow in features,\nso that it covers all kinds of use cases, which makes for the completeness\naspect of a library. Our current SDK supports main Infobip channels, but it&#8217;s\ngrowing in features!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"helps-you\">It helps you<\/h3>\n\n\n\n<p>Taking advantage of the generated, and then customized models, we&#8217;ve been able\nto provide extra help by validating field content prior to sending a request\nover the network. This helps you find errors early, which in turn, helps you\ndetect vital omissions, e.g. which fields are mandatory or what kind of domain\na field has. The models are also easy to serialize and deserialize thanks to\nthe use of <code>serde<\/code> deriving.<\/p>\n\n\n\n<p>Models are convenient to use because you can create a new instance in several\ndifferent ways: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>By calling a <code>new()<\/code> constructor, which enforces required fields<\/li>\n\n\n\n<li>By parsing from JSON or other serialized formats, convenient if you already\nhave that<\/li>\n\n\n\n<li>By calling the <em>true constructors<\/em> in which you set all fields in one\nsentence, which helps with <em>immutability<\/em><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"its-idiomatic\">It&#8217;s idiomatic<\/h3>\n\n\n\n<p>Code that follows the specific style and constructs that are common, natural,\nand beneficial to use in a particular language, is called <em>idiomatic<\/em>. In the\nlibrary, we&#8217;ve used things like <code>new_()<\/code>, <code>with_()<\/code> type of constructors that\nmake it convenient to create instances. Also, we&#8217;ve used <code>Result&lt;T, E&gt;<\/code> enums\nfor error handling, which is the norm in Rust. For every endpoint function in\nthe crate, we have a signature similar to this:<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-rust\" data-lang=\"Rust\"><code>pub async fn send(\n    &self, \n    request_body: SendRequestBody\n) -&gt; Result&lt;SdkResponse&lt;SendResponseBody&gt;, SdkError&gt;<\/code><\/pre><\/div>\n\n\n\n<p>These functions return a <code>Result<\/code> that wraps the case of success or failure. This is the idiomatic way of handling errors in Rust, with an <code>Error<\/code> type that contains details of what went wrong. These errors can then be handled or propagated by the <code>?<\/code> operator. This is the definition of the <code>Error<\/code> enum for our endpoints:<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-rust\" data-lang=\"Rust\"><code>#[derive(Error, Debug)] \npub enum SdkError {\n    #[error(&quot;request body has field errors&quot;)]\n    Validation(#[from] validator::ValidationErrors),\n\n    #[error(&quot;HTTP client error&quot;)]\n    Reqwest(#[from] reqwest::Error),\n\n    #[error(&quot;serialization error&quot;)]\n    Serde(#[from] serde_json::Error),\n\n    #[error(&quot;API request error&quot;)]\n    ApiRequestError(#[from] ApiError),\n\n    #[error(&quot;IO error&quot;)]\n    Io(#[from] std::io::Error), \n} <\/code><\/pre><\/div>\n\n\n\n<p>It has different types to handle everything that can go wrong, for example,\nHTTP errors, serialization errors, etc. For 400\/500 server errors, we have the\nApiError.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"it-follows-established-standards\">It follows established standards<\/h3>\n\n\n\n<p>The Rust community has a great checklist of what aspects to consider for a new\ncrate, found in the <a href=\"https:\/\/rust-lang.github.io\/api-guidelines\/checklist.html\">API Guidelines\nChecklist<\/a>.<\/p>\n\n\n\n<p>Additionally, your library version numbers should make sense, and for that,\nthere is a guide on Semantic versioning especially tailored for Rust, which can\nbe found in the <a href=\"https:\/\/doc.rust-lang.org\/cargo\/reference\/semver.html\">SemVer\ncompatibility<\/a> section\nof the Cargo manual.<\/p>\n\n\n\n<p>Once your code is in a good shape, you are able to do your first publishing on\nCrates.io! For that, there is a section on what you should do in order to make\nyour crate available in the <a href=\"https:\/\/doc.rust-lang.org\/cargo\/reference\/publishing.html\">Publishing on\ncrates.io<\/a> guide of\nthe Cargo reference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"come-visit-our-repository\">Come visit our repository!<\/h2>\n\n\n\n<p>If you are interested in learning more about Rust, and how a library is\ncreated, you can visit our <a href=\"https:\/\/github.com\/infobip-community\/infobip-api-rust-sdk\">GitHub\nRepository<\/a>, where\nyou are welcome to have a look, provide feedback, and even submit a PR!<\/p>\n\n\n\n<p>Thanks for reading!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You might have heard of Rust, the shiny, fancy, [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[28,254,252],"tags":[43,41,76],"coauthors":[156],"class_list":["post-1025","post","type-post","status-publish","format-standard","hentry","category-blog-post","category-engineering-practices","category-tools","tag-api","tag-developer-practices","tag-sdk"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>What makes a good Rust library? - Infobip Developers Hub<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What makes a good Rust library? - Infobip Developers Hub\" \/>\n<meta property=\"og:description\" content=\"You might have heard of Rust, the shiny, fancy, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\" \/>\n<meta property=\"og:site_name\" content=\"Infobip Developers Hub\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/infobip\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-02T13:55:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-11T14:32:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\" \/>\n<meta name=\"author\" content=\"Erick Corona\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@InfobipDev\" \/>\n<meta name=\"twitter:site\" content=\"@InfobipDev\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Erick Corona\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\"},\"author\":{\"name\":\"Erick Corona\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/9e52e4d22fb53cc9a87adc54825c5e5c\"},\"headline\":\"What makes a good Rust library?\",\"datePublished\":\"2022-12-02T13:55:50+00:00\",\"dateModified\":\"2023-09-11T14:32:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\"},\"wordCount\":1332,\"publisher\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage\"},\"thumbnailUrl\":\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\",\"keywords\":[\"API\",\"developer practices\",\"SDK\"],\"articleSection\":[\"Blog Post\",\"Engineering Practices\",\"Tools\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\",\"url\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\",\"name\":\"What makes a good Rust library? - Infobip Developers Hub\",\"isPartOf\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage\"},\"thumbnailUrl\":\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\",\"datePublished\":\"2022-12-02T13:55:50+00:00\",\"dateModified\":\"2023-09-11T14:32:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage\",\"url\":\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\",\"contentUrl\":\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.infobip.com\/developers\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"What makes a good Rust library?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#website\",\"url\":\"https:\/\/www.infobip.com\/developers\/\",\"name\":\"Infobip Developers Hub\",\"description\":\"Build meaningful customer relationships across any channel\",\"publisher\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.infobip.com\/developers\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\",\"name\":\"Infobip Developers Hub\",\"url\":\"https:\/\/www.infobip.com\/developers\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png\",\"contentUrl\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png\",\"width\":696,\"height\":696,\"caption\":\"Infobip Developers Hub\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/infobip\/\",\"https:\/\/x.com\/InfobipDev\",\"https:\/\/www.youtube.com\/channel\/UCUPSTy53VecI5GIir3J3ZbQ\",\"https:\/\/github.com\/infobip-community\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/9e52e4d22fb53cc9a87adc54825c5e5c\",\"name\":\"Erick Corona\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/image\/1d096b53aac31da0002a2066ab28c0f1\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c59cdedbf2c066d0ebbb15c5b1da56b1c5b5e7c49e3c4aaf7410dd1462a7b74c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c59cdedbf2c066d0ebbb15c5b1da56b1c5b5e7c49e3c4aaf7410dd1462a7b74c?s=96&d=mm&r=g\",\"caption\":\"Erick Corona\"},\"description\":\"Erick has been in the software industry for more than 10 years. Currently, he works as a Developer Experience Engineer at Infobip. He's interested in software development, writing, and racing car simulators in his free time.\",\"url\":\"https:\/\/www.infobip.com\/developers\/blog\/author\/erick\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"What makes a good Rust library? - Infobip Developers Hub","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library","og_locale":"en_US","og_type":"article","og_title":"What makes a good Rust library? - Infobip Developers Hub","og_description":"You might have heard of Rust, the shiny, fancy, [&hellip;]","og_url":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library","og_site_name":"Infobip Developers Hub","article_publisher":"https:\/\/www.facebook.com\/infobip\/","article_published_time":"2022-12-02T13:55:50+00:00","article_modified_time":"2023-09-11T14:32:38+00:00","og_image":[{"url":"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png","type":"","width":"","height":""}],"author":"Erick Corona","twitter_card":"summary_large_image","twitter_creator":"@InfobipDev","twitter_site":"@InfobipDev","twitter_misc":{"Written by":"Erick Corona","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#article","isPartOf":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library"},"author":{"name":"Erick Corona","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/9e52e4d22fb53cc9a87adc54825c5e5c"},"headline":"What makes a good Rust library?","datePublished":"2022-12-02T13:55:50+00:00","dateModified":"2023-09-11T14:32:38+00:00","mainEntityOfPage":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library"},"wordCount":1332,"publisher":{"@id":"https:\/\/www.infobip.com\/developers\/#organization"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage"},"thumbnailUrl":"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png","keywords":["API","developer practices","SDK"],"articleSection":["Blog Post","Engineering Practices","Tools"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library","url":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library","name":"What makes a good Rust library? - Infobip Developers Hub","isPartOf":{"@id":"https:\/\/www.infobip.com\/developers\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage"},"thumbnailUrl":"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png","datePublished":"2022-12-02T13:55:50+00:00","dateModified":"2023-09-11T14:32:38+00:00","breadcrumb":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#primaryimage","url":"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png","contentUrl":"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2022\/12\/rust-lib-attr-1024x467.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.infobip.com\/developers\/blog\/what-makes-a-good-rust-library#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.infobip.com\/developers\/"},{"@type":"ListItem","position":2,"name":"What makes a good Rust library?"}]},{"@type":"WebSite","@id":"https:\/\/www.infobip.com\/developers\/#website","url":"https:\/\/www.infobip.com\/developers\/","name":"Infobip Developers Hub","description":"Build meaningful customer relationships across any channel","publisher":{"@id":"https:\/\/www.infobip.com\/developers\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.infobip.com\/developers\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.infobip.com\/developers\/#organization","name":"Infobip Developers Hub","url":"https:\/\/www.infobip.com\/developers\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/","url":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png","contentUrl":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png","width":696,"height":696,"caption":"Infobip Developers Hub"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/infobip\/","https:\/\/x.com\/InfobipDev","https:\/\/www.youtube.com\/channel\/UCUPSTy53VecI5GIir3J3ZbQ","https:\/\/github.com\/infobip-community"]},{"@type":"Person","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/9e52e4d22fb53cc9a87adc54825c5e5c","name":"Erick Corona","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/image\/1d096b53aac31da0002a2066ab28c0f1","url":"https:\/\/secure.gravatar.com\/avatar\/c59cdedbf2c066d0ebbb15c5b1da56b1c5b5e7c49e3c4aaf7410dd1462a7b74c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c59cdedbf2c066d0ebbb15c5b1da56b1c5b5e7c49e3c4aaf7410dd1462a7b74c?s=96&d=mm&r=g","caption":"Erick Corona"},"description":"Erick has been in the software industry for more than 10 years. Currently, he works as a Developer Experience Engineer at Infobip. He's interested in software development, writing, and racing car simulators in his free time.","url":"https:\/\/www.infobip.com\/developers\/blog\/author\/erick"}]}},"_links":{"self":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1025","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/comments?post=1025"}],"version-history":[{"count":6,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1025\/revisions"}],"predecessor-version":[{"id":2124,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1025\/revisions\/2124"}],"wp:attachment":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/media?parent=1025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/categories?post=1025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/tags?post=1025"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/coauthors?post=1025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}