<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>hugozap</title>
	<subtitle>hugozap blog.</subtitle>
	
	<link href="https://www.hugozap.com/feed/feed.xml" rel="self"/>
	<link href="https://www.hugozap.com"/>
	<updated>2026-07-31T00:00:00Z</updated>
	<id>https://hugozap.com/</id>
	<author>
		<name>Hugo Zapata</name>
		<email>hugozap@gmail.com</email>
	</author>
	
	<entry>
		<title>How to finish your side project.</title>
		<link href="https://www.hugozap.com/posts/how-to-finish-your-side-project/"/>
		<updated>2020-04-24T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/how-to-finish-your-side-project/</id>
		<content type="html">&lt;p&gt;&lt;img src=&quot;https://www.hugozap.com/img/hands.jpg&quot; alt=&quot;Illustration by Angélica Delvalle IG: ylikdelvalle&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s no secret that finishing a side project is hard.&lt;/p&gt;
&lt;p&gt;I&#39;ve struggled with some side projects and had success with others. In this post, I&#39;ll focus on the actions and adjustments that have worked for me.&lt;/p&gt;
&lt;p&gt;It&#39;s possible to work on and finish side projects even with a busy schedule, the key is to optimize for interruptability. You will be interrupted so instead of counting on having hours of deep work available, it&#39;s better to be realistic and make some adjustments to use available time in a better way and reducing the cost of interruptions by having tricks to switch context fast.&lt;/p&gt;
&lt;h2 id=&quot;a-failed-side-project-story&quot;&gt;A failed side project story &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#a-failed-side-project-story&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Maybe you are familiar with a similar situation&lt;/p&gt;
&lt;p&gt;At the beginning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High motivation.&lt;/li&gt;
&lt;li&gt;Priority over other tasks.&lt;/li&gt;
&lt;li&gt;Working long hours because it&#39;s fun.&lt;/li&gt;
&lt;li&gt;Desire to work with a new technology&lt;/li&gt;
&lt;li&gt;No problem working on weekends.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After some time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Motivation decreases.&lt;/li&gt;
&lt;li&gt;Feels overwheelming.&lt;/li&gt;
&lt;li&gt;Harder to justify working on the project when there are other responsibilities.&lt;/li&gt;
&lt;li&gt;Other stuff seems more interesting now.&lt;/li&gt;
&lt;li&gt;Forgot how to set things up to continue working on the project.&lt;/li&gt;
&lt;li&gt;Not sure what I was working on.&lt;/li&gt;
&lt;li&gt;Forgetting about the project and archiving it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-challenges-with-side-projects&quot;&gt;The challenges with side projects &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#the-challenges-with-side-projects&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Context switching and high cognitive load is exhausting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Losing interest/ motivation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Perfectionism - never ending projects.&lt;/li&gt;
&lt;li&gt;Impostor syndrome.&lt;/li&gt;
&lt;li&gt;Lack of focus.&lt;/li&gt;
&lt;li&gt;Lack of time.&lt;/li&gt;
&lt;li&gt;Unexpected life events.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;re-framing-the-goal&quot;&gt;Re framing the goal &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#re-framing-the-goal&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I believe you can set yourself for failure from the start if the goal is not clear.&lt;/p&gt;
&lt;p&gt;I&#39;ve been excited about ideas but later found that I was not really invested in the idea and just wanted to explore a cool feature/tool. It&#39;s good to go deeper to your true motivation.&lt;/p&gt;
&lt;p&gt;Feeling overwhelmed can also contribute to abandoning the project, I&#39;ll talk about &lt;strong&gt;small steps&lt;/strong&gt; and why it&#39;s key.&lt;/p&gt;
&lt;p&gt;If your track record includes lots of ambitious projects and none of them finished, then starting with something smaller seems like the logical approach.&lt;/p&gt;
&lt;p&gt;Pick a small battle, maybe just the key feature first, maybe support for just one platform. Cut off features for the first version, remember that there&#39;s a lot of forces against you completing your project so reducing load is important.&lt;/p&gt;
&lt;h2 id=&quot;the-approach&quot;&gt;The approach &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#the-approach&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have a clear idea of what you want to finish, there&#39;s some actions and adjustments to your process that will increase the chance of winning the battle (shipping).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Preparing your environment (painless context switch)&lt;/li&gt;
&lt;li&gt;Work in &lt;strong&gt;Small steps&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Mental warm-up before each session.&lt;/li&gt;
&lt;li&gt;Anticipate and expect interruptions.&lt;/li&gt;
&lt;li&gt;Changing your physical location.&lt;/li&gt;
&lt;li&gt;Writting down the ideas on your mind at the end of the session.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;small-steps-are-key&quot;&gt;Small steps are key &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#small-steps-are-key&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like the idea of not having too many open boxes at the same time, where each box is a task/feature or something that you  started but haven&#39;t finished yet.&lt;/p&gt;
&lt;p&gt;It&#39;s demoralizing to wait weeks or months for a win. Small steps give you small wins, it keeps the journey fun. There&#39;s less change of feeling stuck.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.geepawhill.org/2020/06/26/more-on-small-steps/&quot;&gt;Geepaw Hill&lt;/a&gt; shares excellent resources on the topic of small steps in software.&lt;/p&gt;
&lt;h2 id=&quot;warming-up-before-each-session-to-reduce-cognitive-exhaustion&quot;&gt;Warming up before each session to reduce cognitive exhaustion &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#warming-up-before-each-session-to-reduce-cognitive-exhaustion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before starting actual work, write about what would be good to achieve in the session. I find this ritual valuable as it helps me figure out the next small step. Writing the project goal (high level) every session is also a good way to switch context and reminding yourself what&#39;s it all about.&lt;/p&gt;
&lt;p&gt;I&#39;ll talk about having a &amp;quot;context&amp;quot; log, where you write the current progress, and what to do next. If you have this file, reading the previous session log let&#39;s you resume your work faster.&lt;/p&gt;
&lt;h2 id=&quot;immediate-context-switching&quot;&gt;Immediate context switching &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#immediate-context-switching&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the limited amount of mental energy, is crucial to reduce the number of setup tasks required to do a working session on your project. The goal here is reducing the number of small decisions you have to make to have a working environment.&lt;/p&gt;
&lt;p&gt;This is one of the most important things for me, and the way I approach it is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a separated system User on my laptop.&lt;/li&gt;
&lt;li&gt;Having an email address only for my project.&lt;/li&gt;
&lt;li&gt;Having a &amp;quot;context&amp;quot; file where I log what&#39;s currently happening with my project, usually at the end of a work session.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These have been valuable tools for me, let me explain why:&lt;/p&gt;
&lt;h3 id=&quot;a-separate-system-user-for-your-side-project&quot;&gt;A separate system user for your side project &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#a-separate-system-user-for-your-side-project&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;By creating a separate user, you automatically have all the operative system tools (calendar/notes/reminders , etc.) available ONLY for your project.&lt;/p&gt;
&lt;p&gt;All the files on your desktop will have a relation to your project. This may not seem impressive but think about all the small distractions you find if you use the same user for your personal/work tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Time to find a file (filtering unrelated stuff will bring memories of other things)&lt;/li&gt;
&lt;li&gt;Reminders/calendar notifications not related to your project&lt;/li&gt;
&lt;li&gt;Dealing with other project setups can be stressful.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think it was Seth Godin who recommended having a separate laptop for a side project like writing a book. This is an alternative too.&lt;/p&gt;
&lt;p&gt;You can add more extreme measures like redirecting distracting sites like news or reddit. If you need to login to one of those sites, it&#39;s better to switch user accounts. Try to keep your project user clean.&lt;/p&gt;
&lt;h3 id=&quot;having-an-separate-email-for-your-project&quot;&gt;Having an separate email for your project &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#having-an-separate-email-for-your-project&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hugozap.com/posts/ultimate-info-capturing-tool/&quot;&gt;I&#39;m a fan of email&lt;/a&gt; as a note taking tool, it&#39;s available everywhere, the UI is simple. Having a separate email account lets you capture related notes/ideas/links from any device. This has been useful for me when I&#39;m doing something else and have an idea, or find a resource that can be used to do something I want to incorporate into the project.&lt;/p&gt;
&lt;p&gt;Later, when I log in to my project environment I&#39;ll get the emails with relevant information, no chance of getting distracted with other stuff.&lt;/p&gt;
&lt;h3 id=&quot;the-context-file%2C-(brain-dump).&quot;&gt;The context file, (brain dump). &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#the-context-file%2C-(brain-dump).&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A context file is just a text file where you add a short summary of the current project status and what&#39;s on your mind at the time.&lt;/p&gt;
&lt;p&gt;This has been valuable to me, because the act of writing it down helps me have a clear idea of things I could do next and next time I have time to work on my project I&#39;ll have a starting point and it reduces the cognitive load which maximizes the session efficiency.&lt;/p&gt;
&lt;h2 id=&quot;location&quot;&gt;Location &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#location&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Going to a library or café (when possible) or event to another room and have a dedicated space for your current side project will make a difference.&lt;/p&gt;
&lt;p&gt;Not sure about why, but using the same desk for different work and side projects is not ideal for me. If you can I recommend having a different place that helps you switch context quickly.&lt;/p&gt;
&lt;h2 id=&quot;abandoned-projects-may-not-be-a-failure-after-all.&quot;&gt;Abandoned projects may not be a failure after all. &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#abandoned-projects-may-not-be-a-failure-after-all.&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some abandoned projects end up being an inspiration to create something else years later. Maybe you learned something new, explored an idea, or found a problem not possible to solve with the knowledge and resources you had at the time.&lt;/p&gt;
&lt;p&gt;It&#39;s good to have an open mind and be ok with finding dead-ends, they are powerful teachers.&lt;/p&gt;
&lt;p&gt;However, shipping projects &lt;strong&gt;is awesome&lt;/strong&gt; and by reducing scope and anticipating interruptions you will be able to complete your project and release it to the world.&lt;/p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#resources&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For more information about the benefits of a &amp;quot;small step&amp;quot; approach to software development check the excellent resources from &lt;a href=&quot;https://www.geepawhill.org/2020/06/26/more-on-small-steps/&quot;&gt;Geepaw Hill&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;credits&quot;&gt;Credits &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/how-to-finish-your-side-project/#credits&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Illustration by &lt;a href=&quot;https://www.instagram.com/ylikdelvalle/&quot;&gt;Angelica Delvalle&lt;/a&gt; (In case you need art for your company products contact her, she does awesome stuff!)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Thinking in lists</title>
		<link href="https://www.hugozap.com/posts/thinking-in-lists/"/>
		<updated>2022-01-01T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/thinking-in-lists/</id>
		<content type="html">&lt;p&gt;For years, I&#39;ve experimented with different techniques and tools to help me improve my thinking process. Daily journaling is one of those tools, I initially wrote on a paper notebook but I didn&#39;t have the discipline to keep one notebook only for that purpose (always ended up using it for planning work-related stuff).&lt;/p&gt;
&lt;p&gt;By creating the habit of daily journaling, I can clear my mind (the best time to do it for me is early in the morning). Sometimes the journaling sessions are short, and other times I spend hours on it.&lt;/p&gt;
&lt;p&gt;What I found effective is to move from prose-based journaling to a list-based one.&lt;/p&gt;
&lt;p&gt;It looks like this (vague example)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- Goal for this week
    - Learn about topic x
        - What resources should I use?
            - Buy a book?
                - I may have already something on my kindle
                - Who&#39;s an authority on the topic?
                - Find book recommendations on Reddit
                - Better to find a video course?
                    - Haven&#39;t had much success with those in the past.
						- Why?
							- Too much noise
							- Feels slow
							- Too much variability (depends on narrator skills)
            - Watch youtube videos?
           	 - I&#39;ve found that for totally new topics, watching a couple of videos gives me some context so I&#39;ll start with that.
    - Write that article I&#39;ve been delaying for so long
        - What&#39;s creating resistance and procastination?
        - Outline
            - Start with X
            - Continue with Y
            - End with Z
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the basic idea is that you have a conversation and allow your brain to go to new paths (represented as nested items). This has a few benefits&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can quickly focus on a new idea.&lt;/li&gt;
&lt;li&gt;No need to keep a consistent narrative&lt;/li&gt;
&lt;li&gt;Going back to a previous idea is easy&lt;/li&gt;
&lt;li&gt;No need to have sophisticated tools&lt;/li&gt;
&lt;li&gt;Easy to zoom out and see the big picture.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I use Obsidian to keep track of my daily journaling (using the Daily notes plugin). You can use whatever you like and experiment. Some people like to have sophisticated workflows for note-taking. It&#39;s easy to get distracted by which technique or tool works and end up in a rabbit hole (I&#39;m sometimes guilty of this).&lt;/p&gt;
&lt;p&gt;Anyway, it pays to spend some time clearing your mind and daily writing is a good way to do it.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Using Constraint Solvers with Rust and WebAssembly (Exploration)</title>
		<link href="https://www.hugozap.com/posts/constraint-solvers-rust-wasm/"/>
		<updated>2022-10-12T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/constraint-solvers-rust-wasm/</id>
		<content type="html">&lt;p&gt;Yesterday I spent some time experimenting with linear constraint solvers using Rust and WebAssembly.&lt;/p&gt;
&lt;p&gt;(&lt;a href=&quot;https://github.com/hugozap/rust-constraint-solver-wasm-demo&quot;&gt;Demo repository&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;What is a constraint solver?&lt;/p&gt;
&lt;p&gt;The basic idea is that you specify a problem in terms of restrictions. This restrictions should be expressed as linear expressions.&lt;/p&gt;
&lt;p&gt;UI Layouts are a good fit for linear constraint systems, because you can express the relations among elements in terms of these linear expressions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the top of the box2 element should be equal to the bottom of box3&lt;/li&gt;
&lt;li&gt;the x position of box4 should be equal to the total width/2&lt;/li&gt;
&lt;li&gt;the total width is &amp;gt;= than box2&lt;/li&gt;
&lt;li&gt;the total width is &amp;gt;= than box5&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you have the set of expressions you ask the solver to generate a solution and it will try to produce an optimized set of values that satisfy the constraints.&lt;/p&gt;
&lt;p&gt;When a variable changes, the solver will re compute the solution again.&lt;/p&gt;
&lt;h2 id=&quot;expressing-problems-as-constraints&quot;&gt;Expressing problems as constraints &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#expressing-problems-as-constraints&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think this way of approaching problems is very interesting and aligned with the current trends of AI assisted workflows, that&#39;s one of the reasons I find it useful to improve the problem definition skills and defining constraints is one way to do it.&lt;/p&gt;
&lt;h2 id=&quot;simple-experiment-with-webassembly&quot;&gt;Simple experiment with WebAssembly &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#simple-experiment-with-webassembly&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As part of my Rust and WebAssembly learning journey I like to experiment with topics I find interesting, so let&#39;s try to run a solver in WASM and use it from JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;creating-the-rust-project&quot;&gt;Creating the rust project &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#creating-the-rust-project&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used &lt;code&gt;wasm-pack new&lt;/code&gt; to generate the starter project for my library. It will export a struct that JS will consume and will contain a method to compute the layout.&lt;/p&gt;
&lt;p&gt;Then, I needed to install the cassowary rust crate. At this point I wasn&#39;t sure if it would work in Wasm.&lt;/p&gt;
&lt;p&gt;(Rust project dependencies)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[dependencies]
wasm-bindgen = &amp;quot;0.2.63&amp;quot;
cassowary = &amp;quot;0.3.0&amp;quot;
js-sys = &amp;quot;0.3.44&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;using-the-cassowary-rust-library&quot;&gt;Using the cassowary-rust library &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#using-the-cassowary-rust-library&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There&#39;s an implementation of the cassowary algorithm to find solutions to a set of constraints.&lt;br /&gt;
The high level idea is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new solver instance&lt;/li&gt;
&lt;li&gt;Create variables (with &lt;code&gt;Variable::new()&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our model only has 2 points, each point with a location. Note that we use Variable for the values, because they will be used by the solver.&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; names &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; window_width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window_width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;window_width&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; p1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        y&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; p2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        y&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p1.x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p1.y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p2.x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p2.y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Add the constraints (EQ is the equals operator, there&#39;s also support operators for inequalities)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt; solver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add_constraints&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;                p1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EQ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;REQUIRED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;                p1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EQ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;REQUIRED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;                p2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EQ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;REQUIRED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; window_width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;                p2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EQ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;REQUIRED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; window_width&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our constrained system is simple, there are 2 points and the location of point 2 is determined by the value of the &lt;code&gt;window_width&lt;/code&gt; variable. If &lt;code&gt;window_width&lt;/code&gt; variable changes, p2.y will be updated.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set known values&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We know the window_width variable so let&#39;s tell the solver we want to start with a value for the window_width variable (first we add it as editable)&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;solver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add_edit_variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window_width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STRONG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;solver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;suggest_value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window_width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To retrieve the calculated values we use the solver &lt;code&gt;get_value&lt;/code&gt; method.&lt;br /&gt;
Here we populate a hash map with (name,value) pairs.&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;var&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; names &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; solver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get_value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;var&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;testing-that-the-solver-works&quot;&gt;Testing that the solver works &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#testing-that-the-solver-works&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s add a simple unit test to make sure we set the solver parameters correctly&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[cfg(test)]&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;token module-declaration namespace&quot;&gt;tests&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;token attribute attr-name&quot;&gt;#[test]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;test_calculateLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;br /&gt;            &lt;span class=&quot;token macro property&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;p1.x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token macro property&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;p1.y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token macro property&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;p2.x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token macro property&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;p2.y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;how-to-return-the-values-to-js%3F&quot;&gt;How to return the values to JS? &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#how-to-return-the-values-to-js%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With WebAssembly we have different options to return data.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Return an array of bytes&lt;/li&gt;
&lt;li&gt;Return a pointer and let JS access the WebAssembly memory to retrieve the values&lt;/li&gt;
&lt;li&gt;Serialize to json and return the string&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&#39;ll use the 2nd approach because it&#39;s the fastest. In terms of performance we don&#39;t want to transfer a lot of data between JS and Wasm. A pointer is very small and because JS has access to the WebAssembly memory this will be very fast!&lt;/p&gt;
&lt;p&gt;To return the pointer we have this method&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasm_bindgen]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;get_points&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PointLocation&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;points&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;as_ptr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PointLocation has this shape&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasm_bindgen]&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;PointLocation&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;f64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        y&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;f64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;generating-the-webassembly-package&quot;&gt;Generating the WebAssembly package &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#generating-the-webassembly-package&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;wasm-pack build --target web&lt;/code&gt; the npm compatible package will be generated in the &lt;code&gt;pkg&lt;/code&gt; folder.&lt;br /&gt;
We can include it from our web application now.&lt;/p&gt;
&lt;p&gt;I used the &lt;code&gt;Vite&lt;/code&gt; Bundler, but this is compatible with most bundlers.&lt;/p&gt;
&lt;h2 id=&quot;using-our-wasm-module-from-js&quot;&gt;Using our wasm module from JS &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#using-our-wasm-module-from-js&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After generating the package I added it as a dependency in my web application.&lt;br /&gt;
This step is different for each bundler (vanilla JS is also supported).&lt;/p&gt;
&lt;p&gt;Now in my web application I can access the exported Rust structs and methods&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; init&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; App &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rust-constraint-solver-wasm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;runWasm&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//init will fetch our .wasm file&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wasm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//Let&#39;s create an instance of the exported App struct (defined in rust)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//the main method that will run the solver&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//for demo purposes we are not passing any parameter. In real life &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//we should pass the initial values (e.g the width of the window, positions, etc)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//to get the updated values&lt;/span&gt;&lt;br /&gt;    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update_locations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//We didn&#39;t return the values from update_locations,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//just updated the memory with the values of interest, &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//now we need to access the wasm memory space and retrieve them.&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; points_ptr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get_points&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; points &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Float64Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wasm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;memory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; points_ptr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; points &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When running the app you&#39;ll see in the log, the list of updated values.&lt;br /&gt;
Not very exciting but this opens the opportunity to solve much more interesting problems that can be expressed with linear constraints.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.hugozap.com/img/cassowary-experiment-log.png&quot;&gt;console output&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;what&#39;s-next&quot;&gt;What&#39;s next &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/constraint-solvers-rust-wasm/#what&#39;s-next&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have a proof of concept, we could try creating layout systems for Canvas, WebGL. I see some potential for layout systems that offer a more natural way to arrange elements.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>WebAssembly in the Browser (Basics)</title>
		<link href="https://www.hugozap.com/posts/webassembly-basics-browser/"/>
		<updated>2022-11-02T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/webassembly-basics-browser/</id>
		<content type="html">&lt;p&gt;(As part of my WebAssembly explorations I&#39;ll be sharing some of my learnings as a mix of notes/tutorial/high level overview.&lt;br /&gt;
I won&#39;t detail every step, but I&#39;ll try to explain the concepts and the decisions at least at a high level.)&lt;/p&gt;
&lt;p&gt;In this post I&#39;ll show you how to get started with WebAssembly in the browser using the Rust programming language to create the WebAssembly module.&lt;/p&gt;
&lt;p&gt;With WebAssembly, we have a way to run code created in other languages inside the browser. (You can also use it in the server but I&#39;ll focus on the browser here)&lt;/p&gt;
&lt;h2 id=&quot;the-process-(high-level-overview)&quot;&gt;The process (high level overview) &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#the-process-(high-level-overview)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Write the WebAssembly module in a supported language (Rust, Go, C#, AssemblyScript, etc)&lt;/li&gt;
&lt;li&gt;Compile (instructions depend on the selected language) and generate the binary file with .wasm extension&lt;/li&gt;
&lt;li&gt;Include the .wasm file in your web application, it must be published with your web application&lt;/li&gt;
&lt;li&gt;Load the file in JavaScript and run the WebAssembly exported methods.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&#39;s go through each step.&lt;/p&gt;
&lt;h2 id=&quot;installing-rust-toolchain-(optional)&quot;&gt;Installing rust toolchain (optional) &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#installing-rust-toolchain-(optional)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;(If you don&#39;t want do do it you can skip this step and just download the pre-built package here &lt;a href=&quot;https://github.com/hugozap/rust-format-message-example-library/releases/download/v1/pkg.zip&quot;&gt;https://github.com/hugozap/rust-format-message-example-library/releases/download/v1/pkg.zip&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;If you want to generate the WebAssembly module from Rust you need to install the Rust toolchain from (&lt;a href=&quot;https://rustup.rs/&quot;&gt;https://rustup.rs/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To install wasm-pack (a tool that will help us to generate the npm compatible package):&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cargo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; wasm-pack&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;writing-the-webassembly-module-(optional)&quot;&gt;Writing the WebAssembly module (optional) &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#writing-the-webassembly-module-(optional)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ll use Rust for this example. I&#39;ll use the &lt;code&gt;wasm-bindgen&lt;/code&gt; crate to generate the bindings between Rust and JavaScript.&lt;/p&gt;
&lt;p&gt;The first step is to create a new Rust project with &lt;code&gt;cargo new rust-simple-library --lib&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then we need to add the &lt;code&gt;wasm-bindgen&lt;/code&gt; dependency to our &lt;code&gt;Cargo.toml&lt;/code&gt; file&lt;/p&gt;
&lt;pre class=&quot;language-toml&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;wasm-bindgen&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.2.83&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can start writing our code. We&#39;ll create a simple library that returns an ascii message with the text we pass&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;wasm_bindgen&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;prelude&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasm_bindgen]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;format_message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; max &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//find the longest line&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; line &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; max &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            max &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//print the top line&lt;/span&gt;&lt;br /&gt;    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//print the text&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; line &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;* &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;line&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token comment&quot;&gt;//add spaces to the end of the line&lt;/span&gt;&lt;br /&gt;        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; *\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//print the bottom line&lt;/span&gt;&lt;br /&gt;    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;compiling-the-webassembly-module-(optional)&quot;&gt;Compiling the WebAssembly module (optional) &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#compiling-the-webassembly-module-(optional)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now we&#39;ll compile the code with &lt;code&gt;wasm-pack build --target web&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will generate the &lt;code&gt;pkg&lt;/code&gt; folder with the npm compatible package. We can include it from our web application now.&lt;/p&gt;
&lt;h2 id=&quot;including-the-wasm-module-in-our-web-application&quot;&gt;Including the wasm module in our web application &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#including-the-wasm-module-in-our-web-application&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We need the .wasm and js helper files to be published with our web application. Depending on the bundler we use, we&#39;ll have different ways to include it.&lt;/p&gt;
&lt;p&gt;If you don&#39;t use a bundler you can compile the module with &lt;code&gt;--target no_modules&lt;/code&gt; and include the .wasm file in your web site contents folder.&lt;/p&gt;
&lt;h3 id=&quot;common-bundler-wasm-plugins&quot;&gt;Common bundler wasm plugins &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#common-bundler-wasm-plugins&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For Webpack:&lt;br /&gt;
&lt;a href=&quot;https://github.com/wasm-tool/wasm-pack-plugin&quot;&gt;https://github.com/wasm-tool/wasm-pack-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For Vite:&lt;br /&gt;
&lt;a href=&quot;https://github.com/nshen/vite-plugin-wasm-pack/&quot;&gt;https://github.com/nshen/vite-plugin-wasm-pack/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;using-our-wasm-module-from-js&quot;&gt;Using our wasm module from JS &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#using-our-wasm-module-from-js&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ll import the wasm module in my web application with &lt;code&gt;import init, { printTextInsideRectangle } from &amp;quot;rust-simple-library&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This is possible because wasm-pack generated the bindings for us.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; init&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; format_message &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rust-simple-library&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;runWasm&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//init will fetch our .wasm file&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wasm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;//let&#39;s call the exported method&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format_message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;runWasm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: We need to wrap our code in an async function and call it. This is because we need to wait for the wasm module to be loaded and top level await is not supported yet.&lt;/p&gt;
&lt;p&gt;If we run this code we&#39;ll see the following output in the console&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;****************
* Hello World! *
****************
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what&#39;s-going-on-under-the-hood%3F&quot;&gt;What&#39;s going on under the hood? &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#what&#39;s-going-on-under-the-hood%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you open the js bindings (ascii_simple_message.js) file you&#39;ll see glue code that will call the WebAssembly object to instantiate the module and call the exported methods.&lt;/p&gt;
&lt;p&gt;This is how the .wasm file is loaded&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; input &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;undefined&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ascii_simple_message_bg.wasm&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It uses a simple fetch to load the .wasm file.&lt;/p&gt;
&lt;p&gt;I recommend taking a look at the generated bindings to understand how it works and see the glue code generated by wasm-bindgen. It basically creates proxy objects for each exported method.&lt;/p&gt;
&lt;p&gt;There are some helper methods to convert the arguments and return values to the correct types. This is required because only basic types can be passed/received to the WebAssembly module.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/webassembly-basics-browser/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This was a simple example to show how to get started with WebAssembly in the browser. There are many more things to explore like memory management, calling JavaScript from WebAssembly, serializing/deserializing objects, etc.&lt;/p&gt;
&lt;p&gt;I&#39;ll cover some of these topics in future posts.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Running Rust code in the cloud with AWS Lambda</title>
		<link href="https://www.hugozap.com/posts/rust-aws-lambda/"/>
		<updated>2024-02-14T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/rust-aws-lambda/</id>
		<content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#introduction&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running Rust code in AWS lambda has many benefits, I personally enjoy working with Rust, the strict compiler and the cargo ecosystem. Having a quick way to create serverless functions with Rust seems like a great idea.&lt;/p&gt;
&lt;p&gt;We&#39;ll go through the steps necessary to create a lambda using cloudformation syntax, the AWS CLI and preparing our Rust code to be deployed.&lt;/p&gt;
&lt;h2 id=&quot;required-tools&quot;&gt;Required tools &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#required-tools&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;rustup: for adding the new compilation target (needed for Mac)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cargo-lambda.info/&quot;&gt;cargo lambda&lt;/a&gt;: Helps building rust packages that will target AWS Lambda runtime&lt;/li&gt;
&lt;li&gt;AWS CLI: For deploying the cloudformation stack&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;writing-our-rust-program&quot;&gt;Writing our Rust program &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#writing-our-rust-program&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The code we&#39;ll use is taken from the examples of the &lt;a href=&quot;https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples&quot;&gt;lambda_http&lt;/a&gt; repository. It&#39;s a very simple function that returns a string, it&#39;s enough to test if things work and a useful starter template:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/// Extracted from  https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;lambda_http&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; service_fn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; tracing_subscriber&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; tracing&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;function_handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_event&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// Extract some useful information from the request&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// Return something that implements IntoResponse.&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// It will be serialized to the right response event automatically by the runtime&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content-type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/html&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello AWS Lambda HTTP request&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;new&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[tokio::main]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// required to enable CloudWatch error logging by the runtime&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token namespace&quot;&gt;tracing_subscriber&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;with_max_level&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;tracing&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token comment&quot;&gt;// disable printing the name of the module in every log line.&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;with_target&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token comment&quot;&gt;// disabling time is handy because CloudWatch will add the ingestion time.&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;without_time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;service_fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;function_handler&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idea is simple, you wrap your function handler in a &lt;code&gt;service_fn&lt;/code&gt; and it&#39;s itself wrapped in a &lt;code&gt;run&lt;/code&gt; function. Tokyo is used to provide the async capabilities.&lt;/p&gt;
&lt;h2 id=&quot;lambda_runtime-vs-lambda_http&quot;&gt;lambda_runtime vs lambda_http &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#lambda_runtime-vs-lambda_http&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When I tried the first time I used an example that used &lt;code&gt;lambda_runtime&lt;/code&gt; and got some issues because lambda_runtime does not understand AWS Api Gateway context. I found out that &lt;code&gt;lambda_http&lt;/code&gt; is the right choice for this case as it&#39;s a higher level library that abstracts the API Gateway request/response objects.&lt;/p&gt;
&lt;h2 id=&quot;compiling-the-rust-code&quot;&gt;Compiling the Rust code &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#compiling-the-rust-code&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m using a Mac, the first time I tried to deploy the package I got an error due to executable incompatibilities. I learned I had to target a linux platform so it&#39;s compatible with the AWS Lambda environment.&lt;/p&gt;
&lt;p&gt;Installing the linux target with rustup:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;rustup target &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; x86_64-unknown-linux-musl&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now building the package for the new target using cargo lambda:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cargo&lt;/span&gt; lambda build &lt;span class=&quot;token parameter variable&quot;&gt;--target&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;x86_64-unknown-linux-musl &lt;span class=&quot;token parameter variable&quot;&gt;--release&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;creating-the-lambda-zip-package.&quot;&gt;Creating the lambda zip package. &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#creating-the-lambda-zip-package.&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We now have to create a zip that contains the compiled artifacts created in the compilation step.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;cargo lambda&lt;/code&gt; tool creates a file called &lt;code&gt;bootstrap&lt;/code&gt;in the &lt;code&gt;target/lambda/your-project-name&lt;/code&gt; directory and this is the only file that we need to zip.&lt;/p&gt;
&lt;p&gt;Run the following command to create the zip (from the directory that contains the bootstrap file):&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; lambda-package.zip &lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;creating-the-s3-bucket-to-store-the-lambda-package%3A&quot;&gt;Creating the S3 bucket to store the lambda package: &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#creating-the-s3-bucket-to-store-the-lambda-package%3A&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s create an encrypted S3 bucket to store our lambda zip package.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Replace `rust-lambda-code-test` with your bucket name!&lt;/span&gt;&lt;br /&gt;aws s3api create-bucket &lt;span class=&quot;token parameter variable&quot;&gt;--bucket&lt;/span&gt; rust-lambda-code-test &lt;span class=&quot;token parameter variable&quot;&gt;--region&lt;/span&gt; us-east-1&lt;br /&gt;aws s3api put-bucket-encryption &lt;span class=&quot;token parameter variable&quot;&gt;--bucket&lt;/span&gt; rust-lambda-code-test --server-side-encryption-configuration &lt;span class=&quot;token string&quot;&gt;&#39;{&quot;Rules&quot;:[{&quot;ApplyServerSideEncryptionByDefault&quot;:{&quot;SSEAlgorithm&quot;:&quot;AES256&quot;}}]}&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;the-cloudformation-template&quot;&gt;The Cloudformation template &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#the-cloudformation-template&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used this cloudformation template to create the Lambda in AWS, make sure to adjust the path of the .zip package we created before:&lt;/p&gt;
&lt;p&gt;The parameters defined by this template are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;BucketName: The name of the S3 bucket where the Lambda deployment package is located&lt;/li&gt;
&lt;li&gt;PathToLambdaZip: Local path to the zip package created before&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;** Note: I put the cloudformation template in a file called in the path: cloud-formation/rust-lambda.yaml inside my Rust project, this path will be needed create the stack later **&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2010-09-09&#39;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key atrule&quot;&gt;Parameters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;BucketName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; The name of the S3 bucket where the Lambda deployment package is located&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; your&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;bucket&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;PathToLambdaZip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; The path to the Lambda deployment package in the S3 bucket&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path/to/lambda.zip&lt;br /&gt;&lt;span class=&quot;token key atrule&quot;&gt;Resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;RustLambdaFunction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Lambda&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Function&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; index.handler&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!GetAtt&lt;/span&gt; LambdaExecutionRole.Arn&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; provided.al2&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;S3Bucket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; BucketName&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;S3Key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; PathToLambdaZip&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;MemorySize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;LambdaExecutionRole&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;IAM&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Role&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;AssumeRolePolicyDocument&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2012-10-17&#39;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;Statement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;Effect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Allow&lt;br /&gt;            &lt;span class=&quot;token key atrule&quot;&gt;Principal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;              &lt;span class=&quot;token key atrule&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; lambda.amazonaws.com&lt;br /&gt;            &lt;span class=&quot;token key atrule&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;sts:AssumeRole&#39;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Policies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;PolicyName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; LambdaExecutionPolicy&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;PolicyDocument&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token key atrule&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2012-10-17&#39;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token key atrule&quot;&gt;Statement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;              &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;Effect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Allow&lt;br /&gt;                &lt;span class=&quot;token key atrule&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;logs:*&#39;&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;token key atrule&quot;&gt;Resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;arn:aws:logs:*:*:*&#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;MyApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;ApiGateway&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;RestApi&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; RustServiceAPI&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;Resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;ApiGateway&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Resource&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;DependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyApi&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;RestApiId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyApi&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!GetAtt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;MyApi.RootResourceId&#39;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;PathPart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rustservice&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;ApiGateway&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Method&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;DependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Resource&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;RestApiId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyApi&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;ResourceId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; Resource&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;HttpMethod&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; POST&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;AuthorizationType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; NONE&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Integration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS_PROXY&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;IntegrationHttpMethod&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; POST&lt;br /&gt;        &lt;span class=&quot;token key atrule&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Sub&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RustLambdaFunction.Arn}/invocations&#39;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;MethodResponses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;LambdaInvokePermission&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Lambda&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Permission&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;FunctionName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; RustLambdaFunction&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; lambda&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;InvokeFunction&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;Principal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apigateway.amazonaws.com&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;SourceArn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Sub&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyApi}/*/*/*&#39;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;ApiDeployment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;ApiGateway&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Deployment&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;DependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Method&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;RestApiId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyApi&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;StageName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dev&lt;br /&gt;&lt;span class=&quot;token key atrule&quot;&gt;Outputs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;ApiEndpoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;API Gateway endpoint URL for the Rust service&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Sub&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/Dev/rustservice&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;deploying-the-cloudformation-stack&quot;&gt;Deploying the Cloudformation stack &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#deploying-the-cloudformation-stack&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To deploy de stack, run the following command providing the required parameters for bucket name and zip package location. The AWS CLI tool will start the process of deploying and you can see the result on the AWS Console:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;aws cloudformation create-stack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  --stack-name RustLambdaServiceTestStack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  --template-body file://cloud-formation/rust-lambda.yaml &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token parameter variable&quot;&gt;--parameters&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ParameterKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;BucketName,ParameterValue&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;rust-lambda-code-test &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;               &lt;span class=&quot;token assign-left variable&quot;&gt;ParameterKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;PathToLambdaZip,ParameterValue&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;lambda-package.zip &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token parameter variable&quot;&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM CAPABILITY_NAMED_IAM&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;updating-our-rust-code&quot;&gt;Updating our Rust code &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#updating-our-rust-code&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you change your code, you&#39;ll need to build and create the zip file again. Then run the following command to update the stack:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;aws cloudformation update-stack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  --stack-name RustLambdaServiceTestStack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  --template-body file://cloud-formation/rust-lambda.yaml &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token parameter variable&quot;&gt;--parameters&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ParameterKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;BucketName,ParameterValue&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;rust-lambda-code-test &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;               &lt;span class=&quot;token assign-left variable&quot;&gt;ParameterKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;PathToLambdaZip,ParameterValue&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;lambda-package-v2.zip &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token parameter variable&quot;&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM CAPABILITY_NAMED_IAM&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;obtaining-the-api-url&quot;&gt;Obtaining the API URL &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#obtaining-the-api-url&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Go to the AWS Console -&amp;gt; Cloud Formation and look for the stack you created. Click on the Outputs tab and you&#39;ll find the URL of the API endpoint you can use.&lt;/p&gt;
&lt;h2 id=&quot;testing-the-lambda&quot;&gt;Testing the Lambda &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#testing-the-lambda&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To test that our lambda works send an HTTP request using curl or any other tool:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; https://&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;generated-id&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.execute-api.us-east-1.amazonaws.com/Dev/rustservice&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Hello AWS Lambda HTTP request&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://www.hugozap.com/posts/rust-aws-lambda/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Having a way to quickly deploy Rust code as serverless functions is very useful. Not being dependent on a runtime makes things simpler in terms of compiling/updating and deployment of our code.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Using NATS(JetStream) as Gorilla session provider in Go</title>
		<link href="https://www.hugozap.com/posts/nats-gorilla-sessions/"/>
		<updated>2024-09-28T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/nats-gorilla-sessions/</id>
		<content type="html">&lt;p&gt;For a fun side project I&#39;m using NATS, specifically JetStream, its key value storage engine.&lt;/p&gt;
&lt;p&gt;I wanted to handle sessions using NATS with the gorilla Golang package, but didn&#39;t find a provider.&lt;/p&gt;
&lt;p&gt;Turns out building one for it was not hard thanks to the easy to implement gorilla interface for session management.&lt;/p&gt;
&lt;p&gt;Usage:&lt;/p&gt;
&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;github.com/hugozap/natsstore&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;store&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; natsstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;js&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;myapp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;secret-key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can get it from here  here: &lt;a href=&quot;https://github.com/hugozap/natsstore&quot;&gt;https://github.com/hugozap/natsstore&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Diagram Codes Desktop is free now</title>
		<link href="https://www.hugozap.com/posts/diagram-codes-free/"/>
		<updated>2025-10-30T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/diagram-codes-free/</id>
		<content type="html">&lt;p&gt;Download here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(MacOS) &lt;a href=&quot;https://github.com/hugozap/diagram-codes-desktop-app/releases/download/v1.0.40/Diagram.codes.Studio-1.0.40-macos.zip&quot;&gt;https://github.com/hugozap/diagram-codes-desktop-app/releases/download/v1.0.40/Diagram.codes.Studio-1.0.40-macos.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(Windows) &lt;a href=&quot;https://github.com/hugozap/diagram-codes-desktop-app/releases/download/v1.0.40/Diagram.codes.Studio-1.0.40-arm64-win.zip&quot;&gt;https://github.com/hugozap/diagram-codes-desktop-app/releases/download/v1.0.40/Diagram.codes.Studio-1.0.40-arm64-win.zip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Link to documentation:&lt;br /&gt;
&lt;a href=&quot;https://hugozap.github.io/diagram-codes-desktop-app/#/&quot;&gt;https://hugozap.github.io/diagram-codes-desktop-app/#/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some time ago I created a software for creating Diagrams from simple text syntax called Diagram.Codes. Even though I stopped working on the project, it&#39;s still a great utility for creating diagrams and it&#39;s used by users in different industries and now you can use it for free.&lt;/p&gt;
&lt;p&gt;I love local tools you can install and use even with no connectivity and I wanted to create an application for quickly creating diagrams and export them.&lt;/p&gt;
&lt;p&gt;Working on Diagramm Codes I learnt a lot, from designing custom Domain Specific Languages (DSL).&lt;/p&gt;
&lt;p&gt;I haven&#39;t published the code yet but I may do it in the future when I have some time for cleaning it.&lt;/p&gt;
&lt;p&gt;I&#39;m currently working on an improved layout engine created in Rust as a hobby project and hope to release some derived tools in the future.&lt;/p&gt;
&lt;p&gt;Hope you find it useful.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>mcp-inspector, a TUI to debug MCP traffic</title>
		<link href="https://www.hugozap.com/posts/mcp-inspector/"/>
		<updated>2026-07-31T00:00:00Z</updated>
		<id>https://www.hugozap.com/posts/mcp-inspector/</id>
		<content type="html">&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/hugozap/mcp-inspector&quot;&gt;https://github.com/hugozap/mcp-inspector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.hugozap.com/img/mcp-inspector.png&quot; alt=&quot;mcp-inspector TUI showing live MCP traffic&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you&#39;ve built or debugged an MCP (Model Context Protocol) server, you know the usual routine: reading raw JSON from logs or sprinkling print statements to see what&#39;s actually being sent back and forth.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mcp-inspector&lt;/code&gt; is a small terminal tool I built to fix that. It sits between an MCP client and server as a proxy, captures every message, and lets you browse them live in a navigable TUI — no configuration needed.&lt;/p&gt;
&lt;p&gt;It runs headlessly as the actual server command (for example inside Claude Desktop&#39;s config), broadcasting traffic over a Unix socket, while &lt;code&gt;mcp-inspector view&lt;/code&gt; connects from any terminal to show requests, responses, notifications and errors in real time. You can filter by message type, search live, and export a session to NDJSON.&lt;/p&gt;
&lt;p&gt;It&#39;s written in Rust and available on &lt;a href=&quot;http://crates.io/&quot;&gt;crates.io&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cargo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; mcp-inspector&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SSE/HTTP proxy mode and pre-built binaries are on the roadmap.&lt;/p&gt;
</content>
	</entry>
</feed>
