<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Pragma</title>
    <description>The latest articles on Forem by Pragma (@pragmalang).</description>
    <link>https://forem.com/pragmalang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1027%2F78bbc6b6-2281-46a6-ba16-847fb4e626ab.png</url>
      <title>Forem: Pragma</title>
      <link>https://forem.com/pragmalang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pragmalang"/>
    <language>en</language>
    <item>
      <title>Never Used GraphQL? Fear Not!</title>
      <dc:creator>Muhammad Tabaza</dc:creator>
      <pubDate>Tue, 29 Dec 2020 11:53:54 +0000</pubDate>
      <link>https://forem.com/pragmalang/never-used-graphql-fear-not-46of</link>
      <guid>https://forem.com/pragmalang/never-used-graphql-fear-not-46of</guid>
      <description>&lt;p&gt;This article is a practical introduction to &lt;a href="https://graphql.org/"&gt;GraphQL&lt;/a&gt; that enables you to get started building beautiful APIs with Pragmalang.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is GraphQL?
&lt;/h2&gt;

&lt;p&gt;GraphQL is a language specification released by Facebook and standardized in 2015. The language is designed to make retrieving data from front-end applications easier for developers. Some of its advantages are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type-Safe Communication&lt;/strong&gt;: You always know the type/shape of the data you're receiving, and the type of data the server expects from you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard Documentation&lt;/strong&gt;: All GraphQL APIs must follow a certain standard where it comes to documentation. Many tools know how to interpret this documentation by &lt;a href="https://spec.graphql.org/June2018/#sec-Introspection"&gt;&lt;em&gt;introspecting&lt;/em&gt;&lt;/a&gt; the API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling&lt;/strong&gt;: Since GraphQL is a standard, many tools are designed to work with all GraphQL APIs, such as tools that generate TypeScript definitions based on the GraphQL &lt;em&gt;schema&lt;/em&gt; to be used in your Web app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Underfetching/Overfetching Of Data&lt;/strong&gt;: You select exactly the data that you need, and you can perform multiple operations within a single query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GraphQL is actually two languages smashed into one: a &lt;em&gt;schema definition language&lt;/em&gt;, and a &lt;em&gt;query language&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Schema Definition Language
&lt;/h2&gt;

&lt;p&gt;The schema definition language is what is used to describe the types of data that the API operates on, and what the API is capable of doing with said types.For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a type definition&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# '!' means "required" or "not nullable"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;friends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Character&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# '[]' mean "array". Types can be recursive&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;homeWorld&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Planet&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Types can relate to each other&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Another type definition&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Planet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;climate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# A special type definition that specifies&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# the queries that a client can perform&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;getCharacter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Character&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;#            ^^^^^^^^^^^^^   ^^^^^^^^^&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;#           Query Arguments  Query Return Type&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;# Note that the return type is `Character`, not `Character!`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Comments in schema definitions are typically used for documentation. Comments in the example above were used for clarification purposes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GraphQL APIs have three types of operations that a client can perform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries: Simple retrieval of data&lt;/li&gt;
&lt;li&gt;Mutations: Changes to existing data, or addition of new data.&lt;/li&gt;
&lt;li&gt;Subscriptions: Retrieval of dta over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When developing a GraphQL API, you typically need to specify the queries, mutations, and subscriptions that your server can handle. In the example above, the server is only capable of performing a single query that takes a name of a character, and returns that character. But here's the catch: &lt;em&gt;you need to specify **how&lt;/em&gt;* the query is handled*. Using traditional GraphQL frameworks, you would need to define what are known as &lt;em&gt;resolvers&lt;/em&gt; to specify how &lt;em&gt;each field&lt;/em&gt; of the type is fetched from the database. &lt;/p&gt;

&lt;h2&gt;
  
  
  Query Language
&lt;/h2&gt;

&lt;p&gt;Once you're done writing a GraphQL API, you can use one of many GraphQL clients to send operations to your server. Most GraphQL APIs come with a &lt;a href="https://github.com/graphql/graphiql/tree/main/packages/graphiql#readme"&gt;GraphQL playground&lt;/a&gt; that you can use to write queries, and click a button to send them to the server, and display the JSON result. But when you're building a graphical application, you would want to use a &lt;a href="https://www.apollographql.com/docs/react/"&gt;client library&lt;/a&gt; from your code. An example query would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;rick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getCharacter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rick Sanchez"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# We gave the operation a 'rick' alias&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Rick's name, just to make sure&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;friends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# We only want their names&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;homeWorld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# We only want the name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query - if Rick exists in the database - would return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rick"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rick Sanchez"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"friends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"homeWorld"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Earth"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Rick's &lt;code&gt;friends&lt;/code&gt; array is empty because he has no friends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where Does Pragma Come In?
&lt;/h2&gt;

&lt;p&gt;When you're developing a GraphQL API, you need to specify the schema with all the required operations and types, and then implement resolvers for these operations. Of course, you would need to set up the database first.&lt;/p&gt;

&lt;p&gt;What Pragma does is that it only requires that you define a Pragma schema. That's it! It generates a database, GraphQL schema, and all the operations you would need. Plus, with very simple syntax, you can extend the functionality of these operations using serverless functions that you &lt;code&gt;import&lt;/code&gt; as if you were using a normal function from a library. Here's an example Pragma schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config { projectName = "character_api" }

@1 model Character {
  @1 name: String @primary
  @2 friends: [Character]
  @3 homeWorld: Planet
}

@2 model Planet {
  @1 name: String
  @2 climate: String
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the small differences between the Pragma schema and the GraphQL schema. In Pragma, the equivalent of a GraphQL &lt;code&gt;type&lt;/code&gt; is a &lt;code&gt;model&lt;/code&gt;. Models and model fields need to have unique &lt;em&gt;indices&lt;/em&gt; (e.g. &lt;code&gt;@1&lt;/code&gt;, &lt;code&gt;@5&lt;/code&gt;), which enables Pragma to perform most database migrations automatically based on changes to the schema.&lt;/p&gt;

&lt;p&gt;You can explore the GraphQL API generated by Pragma by running the above schema (see &lt;a href="https://pragmalang.com/docs/install"&gt;Install Pragma&lt;/a&gt;), or you can check out another example at &lt;a href="https://pragmalang.com/docs/api"&gt;The Generated API&lt;/a&gt; section of the documentation.&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback, join our &lt;a href="https://discordapp.com/invite/gbhDnfC"&gt;Discord channel&lt;/a&gt;, or leave a comment!&lt;/p&gt;

&lt;p&gt;Go start building that new idea you had last week! It would only take a few minutes :)&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>pragmalang</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Pragma: A Language for Building GraphQL APIs In No Time</title>
      <dc:creator>Muhammad Tabaza</dc:creator>
      <pubDate>Thu, 29 Oct 2020 16:53:22 +0000</pubDate>
      <link>https://forem.com/pragmalang/pragma-a-language-for-building-graphql-apis-in-no-time-800</link>
      <guid>https://forem.com/pragmalang/pragma-a-language-for-building-graphql-apis-in-no-time-800</guid>
      <description>&lt;p&gt;We're very excited to announce the first release of Pragma: An &lt;a href="https://github.com/pragmalang/pragma"&gt;open-source&lt;/a&gt; domain-specific language for building GraphQL APIs by defining data models, and their associated validation/transformation, and authorization logic. Pragma takes your data model definitions, and automatically generates a fully functioning GraphQL API that you can use right away.&lt;/p&gt;

&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;Building a GraphQL API isn't a simple task. Writing a small API to create, read, update, and delete data in a database can take many hours, and lots of knowledge of the GraphQL framework and the language you're using.&lt;/p&gt;

&lt;p&gt;Pragma aims to simplify this process by being incredibly easy to lean, fast to work in, trivial to set up, and very easy to maintain.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Does Pragma Offer?
&lt;/h1&gt;

&lt;p&gt;Pragma offers a way to very quickly build incredibly powerful, and extensible APIs. It supports use of serverless functions written in many languages for data validation and transformation, and also in user authorization, which is built into the language. These languages include JavaScript, Python, Go, Swift, Rust, Ruby, PHP, Java, Scala, and Ballerina.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can I Use It?
&lt;/h1&gt;

&lt;p&gt;You can visit the &lt;a href="https://docs.pragmalang.com"&gt;documentation&lt;/a&gt; and read the Getting Started section to install Pragma, and follow a tutorial where you get to build a basic Todo application.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can I Contribute?
&lt;/h1&gt;

&lt;p&gt;You can help by opening GitHub issues for any bugs you come across, or opening a pull request to improve documentation. You can read the &lt;a href="https://github.com/pragmalang/pragma#contributing"&gt;contributing&lt;/a&gt; section in the README to learn how to start hacking on Pragma itself. Any help is greatly appreciated.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Do I Stay In Touch?
&lt;/h1&gt;

&lt;p&gt;You can follow Pragma on Twitter &lt;a href="https://twitter.com/pragmalang"&gt;@pragmalang&lt;/a&gt;, and here on DEV. You can also join our &lt;a href="https://discord.gg/hAS9FzY"&gt;Discord server&lt;/a&gt; for a chat. We'd love to talk to you guys and learn from your experiences.&lt;/p&gt;

&lt;p&gt;We truly wish you enjoy the development experience we're creating as much as we enjoy working on it! Happy hacking everyone!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>showdev</category>
      <category>javascript</category>
      <category>python</category>
    </item>
    <item>
      <title>Parsing The World with Rust and POM</title>
      <dc:creator>Muhammad Tabaza</dc:creator>
      <pubDate>Wed, 14 Aug 2019 12:09:16 +0000</pubDate>
      <link>https://forem.com/pragmalang/parsing-the-world-with-rust-and-pom-eb6</link>
      <guid>https://forem.com/pragmalang/parsing-the-world-with-rust-and-pom-eb6</guid>
      <description>&lt;p&gt;As programmers, we spend a lot of time dealing with strings of text. Very often, we receive text as input from users, or we read text files and try to understand their content.&lt;/p&gt;

&lt;p&gt;In many cases, we use regular expressions to see if the text matches a certain pattern, or to extract some information from the string. For example, if you receive a username as form input, and you want to make sure that it doesn't contain any spaces, you can use a regex like &lt;code&gt;"^\S+$"&lt;/code&gt; to match a string with one or more non-white space characters (&lt;code&gt;^&lt;/code&gt; denotes the beginning of the string, &lt;code&gt;\S&lt;/code&gt; denotes a non-white space character, &lt;code&gt;+&lt;/code&gt; denotes repetition for one or more times, and &lt;code&gt;$&lt;/code&gt; denotes the end of the string). You might even write a function like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;has_whitespaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Can you spot the bug in the code?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what if you're trying to parse the contents of more complex strings. Say, a JSON string, a CSV (Coma-Separated Values) file, or even a program? If you don't use existing library functions, you're going to have a hard time using regular expressions and string methods.&lt;/p&gt;

&lt;p&gt;In this article, we'll be exploring the &lt;a href="https://github.com/J-F-Liu/pom"&gt;POM&lt;/a&gt; library, which offers a really cool interface for intuitively defining and combining parsers. Using this library, you can conveniently define the entire grammar of a formal language (perhaps your own new programming language?) &lt;/p&gt;

&lt;p&gt;POM is an implementation of a &lt;a href="https://en.wikipedia.org/wiki/Parsing_expression_grammar"&gt;PEG&lt;/a&gt; (Parsing Expression Grammar,) which is a definition of a formal language in terms of symbols, string expressions, and rules.&lt;/p&gt;

&lt;p&gt;For example, if we were to define a rule for parsing a variable definition such as: &lt;code&gt;let  x = 1;&lt;/code&gt;, we would say that &lt;code&gt;let&lt;/code&gt; is a sequence of symbols, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;, and  spaces are symbols, and &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; are string expressions. A variable definition consists of the &lt;code&gt;let&lt;/code&gt; sequence, followed by a space, followed by a &lt;strong&gt;valid identifier&lt;/strong&gt; (&lt;code&gt;x&lt;/code&gt;, for example,) followed by zero or more spaces, followed by the &lt;code&gt;=&lt;/code&gt; symbol, followed by zero or more spaces, followed by a valid expression (&lt;code&gt;1&lt;/code&gt; in this example,) followed by zero or more spaces and the &lt;code&gt;;&lt;/code&gt; symbol. A bit verbose, isn't it? Such are the definitions of formal languages.&lt;/p&gt;

&lt;p&gt;Thankfully, POM provides a very declarative way of defining these rules. It allows us to define different rules for parsing each small piece of text, and then combine them using arithmetic and logical operators to form more complex rules. These operators are called &lt;em&gt;parser combinators&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;POM defines a type called: &lt;code&gt;Parser&lt;/code&gt;, which is used to encode parsing rules. A parser can be constructed using many of the pre-defined parsers that the library provides, such as the &lt;code&gt;sym&lt;/code&gt; and &lt;code&gt;seq&lt;/code&gt; functions. The above example of a variable definition can be expressed in POM as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;char_class&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;variable_def&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;valid_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alphanum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;valid_expr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;one_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"0123456789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.convert&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="nf"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"let"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;valid_id&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;valid_expr&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;';'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down the code:&lt;br&gt;
1 - We import all the contents of &lt;code&gt;pom::char_class&lt;/code&gt;, which exports &lt;br&gt;
predicates such as &lt;code&gt;alpha&lt;/code&gt;, and &lt;code&gt;alphanum&lt;/code&gt;. We use these predicates to &lt;br&gt;
test the type of input characters.&lt;br&gt;
&lt;code&gt;pom::parser&lt;/code&gt; exports &lt;code&gt;seq&lt;/code&gt;, and &lt;code&gt;sym&lt;/code&gt; among other functions that return &lt;br&gt;
&lt;code&gt;Parser&lt;/code&gt;s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;char_class&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - The &lt;code&gt;variable_def&lt;/code&gt; function takes no arguments, and return a &lt;code&gt;Parser&lt;/code&gt; &lt;br&gt;
with the lifetime &lt;code&gt;'a&lt;/code&gt; that accepts &lt;code&gt;u8&lt;/code&gt;s (character bytes) as input, and &lt;br&gt;
outputs a tuple of &lt;code&gt;(String, u32)&lt;/code&gt;. The tuple encodes the variable's &lt;br&gt;
identifier, and its value (we limit valid values to 9-digit positive &lt;br&gt;
integers for simplicity's sake.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;variable_def&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - A valid variable identifier consists of at least one alphabetic character, followed by zero or more alphanumeric characters. We use the &lt;code&gt;is_a&lt;/code&gt; parser to test that the first character of the variable id &lt;code&gt;is_a(alpha)&lt;/code&gt;, and that the rest of the id &lt;code&gt;is_a(alphanum)&lt;/code&gt;.&lt;br&gt;
Notice how the &lt;code&gt;+&lt;/code&gt; operator is used to combine the two parts of the variable identifier. It returns a tuple containing the results of both operands, which we then destructure in the &lt;code&gt;map&lt;/code&gt; method call. &lt;code&gt;map&lt;/code&gt; is used to transform the result of a parser, and return a new parser. In this case: &lt;code&gt;(is_a(alpha) + is_a(alphanum).repeat(0..))&lt;/code&gt; returns a &lt;code&gt;Parser&amp;lt;'a, u8, (u8, Vec&amp;lt;u8&amp;gt;)&amp;gt;&lt;/code&gt; (the first character and the rest of the characters,) which we then transform into a &lt;code&gt;Parser&amp;lt;'a, u8, String&amp;gt;&lt;/code&gt; (the whole identifier) by concatenating the first character and the rest of the characters using &lt;code&gt;format!&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;valid_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alphanum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - A valid expression is defined as 1 to 9 numbers converted to a &lt;code&gt;String&lt;/code&gt; which is then parsed as a &lt;code&gt;u32&lt;/code&gt;. &lt;code&gt;convert&lt;/code&gt; is used here instead of &lt;code&gt;map&lt;/code&gt; because &lt;code&gt;String::from_utf8&lt;/code&gt; returns a &lt;code&gt;Result&lt;/code&gt;, so the parser wouldn't match the expression if the result of &lt;code&gt;String::from_utf8&lt;/code&gt; is &lt;code&gt;Err&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;valid_expr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;one_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"0123456789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.convert&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 - The returned parser is a combination of the symbols mentioned above mixed with some spaces, and a valid identifier and expression. The &lt;code&gt;*&lt;/code&gt; operator combines two parsers and returns the result of the right-hand parser. So &lt;code&gt;Parser&amp;lt;'a, u8, T&amp;gt; * Parser&amp;lt;'a, u8, U&amp;gt; = Parser&amp;lt;'a, u8, U&amp;gt;&lt;/code&gt;.  We also see the &lt;code&gt;-&lt;/code&gt; operator in use, which combines two parsers and returns a parser with the value of the left-hand parser. These operators follow the same precedence rules as normal arithmetic operators in Rust.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"let"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;valid_id&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;valid_expr&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="sc"&gt;';'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Take a look at &lt;a href="https://github.com/J-F-Liu/pom#list-of-predefined-parsers-and-combinators"&gt;this handy table of parser combinators&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now to test our parser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_variable_parser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;valid_variable_byte_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"let v1 = 42;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;variable_def&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valid_variable_byte_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"v1"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;invalid_variable_byte_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"let nosemicolon = 42"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;variable_def&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalid_variable_byte_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Incomplete&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;invalid_variable_byte_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"let morethan9digits = 1234567890;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;variable_def&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalid_variable_byte_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parsed_variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;pom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mismatch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"expect: 59, found: 48"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using POM to parse a variable definition of a positive integer value might seem overkill, but try to imagine using it to parse an entire programming language.&lt;/p&gt;

&lt;p&gt;I hope you found this article helpful. Now enjoy parsing every string in your way.&lt;/p&gt;

&lt;p&gt;Special thanks to &lt;a href="https://github.com/J-F-Liu"&gt;Junfeng Liu&lt;/a&gt; and all contributors for creating an amazing library. You deserve a cookie 🍪&lt;/p&gt;

</description>
      <category>rust</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
