<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="141306" data-post-id="141306">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="edescourtis" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/edescourtis/120/8858_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  edescourtis
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/sunny-g" rel="nofollow">@sunny-g</a></p>
<blockquote>
<p><a class="mention" href="/u/edescourtis" rel="nofollow">@edescourtis</a> So to make sure I understand your use case, you have a JSON-RPC server sending and receiving JSON, and you would ideally want  <code>serde_rustler</code>  to decode JSON into Erlang terms and vice versa?</p>
</blockquote>
<p>No, I would simply like the <em>structure</em> to be essentially the same as for the JSON serialization. Meaning if I used the JSON serializer (<code>serde_json</code>) and then run <code>Jason.decode/1</code> I would get the same value as getting an Erlang term from <code>serde_rustler</code>.</p>
<blockquote>
<p>Regardless, can you provide some data structure examples (or preferably code snippets) to illustrate this shortcoming?</p>
</blockquote>
<p><strong>Rust</strong> <code>struct Rgb { r: u8, g: u8, b: u8 }</code> <strong>Elixir</strong> <code>%Rgb{ r: u8, g: u8, b: u8 }</code><br>
<strong>Rust</strong> <code>struct Rgb { r: u8, g: u8, b: u8 }</code> <strong>JSON</strong> <code>{"r": u8, "g": u8, "b": u8}</code><br>
<strong>Rust</strong> <code>struct Millimeters(u8)</code> <strong>Elixir</strong> <code>{:Millimeters, u8}</code><br>
<strong>Rust</strong> <code>struct Millimeters(u8)</code> <strong>JSON</strong> <code>u8</code></p>
<p>The main issue here is when things get big and nested.</p>
<p>In my view it would be way better if it looked like:</p>
<p><strong>Rust</strong> <code>struct Rgb { r: u8, g: u8, b: u8 }</code> <strong>Elixir</strong> <code>%{r: u8, g: u8, b: u8}</code><br>
<strong>Rust</strong> <code>struct Millimeters(u8)</code> <strong>Elixir</strong> <code>u8</code></p>
<blockquote>
<p>But this library only addresses performance issues for NIFs performing JSON (or any kind of) (de)serialization, so it’s still unclear to me what exactly is not working for you.</p>
</blockquote>
<p>I was just explaining the common use case. A NIF avoids interprocess boundaries and network boundaries, Erlang terms avoid high serialization and deserialization overhead (this is where <code>serde_rustler</code> plays a role).</p>
<p>That said I am not saying that <code>serde_rustler</code> should not be able to annotate types the way it does (maybe there are use cases for that). I am simply saying that for most use cases I care about it creates problems significant enough I can’t use it at all.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="141306" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/serde-rustler-serde-serializer-and-deserializer-for-your-rust-rustler-nifs/23024/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-141306" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="141306"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="141307" data-post-id="141307">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="edescourtis" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/edescourtis/120/8858_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  edescourtis
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>I made this choice for newtype structs + variants and tuples + tuple structs + variants deliberately, but am up for discussion to change it.</p>
</blockquote>
<p>I think it would be beneficial to have both and let the developer choose which one to use.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="141307" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/serde-rustler-serde-serializer-and-deserializer-for-your-rust-rustler-nifs/23024/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-141307" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="141307"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="142169" data-post-id="142169">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sunny-g" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sunny-g/120/6826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sunny-g
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/edescourtis" rel="nofollow">@edescourtis</a></p>
<blockquote>
<p>Shouldn’t be  <em>too</em>  hard to add an attribute to allow people to define how to serialize something back and forth, either custom serialization or some pre-built ones, such as for struct representations or so?</p>
</blockquote>
<blockquote>
<p><strong>Rust</strong>   <code>struct Rgb { r: u8, g: u8, b: u8 }</code>   <strong>Elixir</strong>   <code>%Rgb{ r: u8, g: u8, b: u8 }</code><br>
<strong>Rust</strong>   <code>struct Rgb { r: u8, g: u8, b: u8 }</code>   <strong>JSON</strong>   <code>{"r": u8, "g": u8, "b": u8}</code><br>
<strong>Rust</strong>   <code>struct Millimeters(u8)</code>   <strong>Elixir</strong>   <code>{:Millimeters, u8}</code><br>
<strong>Rust</strong>   <code>struct Millimeters(u8)</code>   <strong>JSON</strong>   <code>u8</code></p>
</blockquote>
<blockquote>
<p>I think it would be beneficial to have both and let the developer choose which one to use.</p>
</blockquote>
<p>I believe there is already an opt-in fix, one I mentioned earlier - attaching <a href="https://serde.rs/attributes.html" rel="noopener nofollow ugc">serde attributes</a> to your types to dictate how they should be serialized or deserialized (or, barring that, implementing <code>Serialize</code> and <code>Deserialize</code> manually for those types).</p>
<p>So the newtype and braced single-field structs should be tagged as such:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">#[derive(Serialize)]
#[serde(transparent)]
struct Millimeters(u8);
</code></pre>
<p>and any enums should look like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">#[derive(Serialize)]
#[serde(untagged)]
enum Coordinates {
  TwoD(u8, u8),
  ThreeD(u8, u8, u8),
}
</code></pre>
<p>Let me know if that covers most of the problems. If not, I’ll look into adding a macro or two.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="142169" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/serde-rustler-serde-serializer-and-deserializer-for-your-rust-rustler-nifs/23024/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-142169" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="142169"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="143870" data-post-id="143870">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="edescourtis" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/edescourtis/120/8858_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  edescourtis
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sunny-g" data-post="14" data-topic="23024">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sunny-g/48/6826_2.png" class="avatar"> sunny-g:</div>
<blockquote>
<p>I believe there is already an opt-in fix, one I mentioned earlier - attaching <a href="https://serde.rs/attributes.html" rel="noopener nofollow ugc">serde attributes</a> to your types to dictate how they should be serialized or deserialized (or, barring that, implementing <code>Serialize</code> and <code>Deserialize</code> manually for those types).</p>
</blockquote>
</aside>
<p>Yes, I could do that if it was my code. Unfortunately, most of the time it is to integrate some code I didn’t write with some Elixir project I am working on by creating a nif library (which includes the foreign code as a submodule). The main issue I have with manually implementing <code>Serialize</code> and <code>Deserialize</code> is that these types change and cause my library to break often. This is not good for maintenance and produces a fragile environment where versions have to be matched closely and changes need to be made constantly. I would like to avoid that if possible. If someone else who owns the foreign codebase is maintaining some existing json serialization it would be nice to piggyback on top of that.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="143870" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/serde-rustler-serde-serializer-and-deserializer-for-your-rust-rustler-nifs/23024/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-143870" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="143870"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>