Skip to content

Commit 4c415a4

Browse files
committed
Refactor podcast_quote shortcode to infer id and slug automatically
1 parent a2516a3 commit 4c415a4

2 files changed

Lines changed: 37 additions & 57 deletions

File tree

content/learn/migration-guides/typescript-to-rust/index.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ Your background with TypeScript's type system is a real advantage. You already t
6666
The main tradeoff you'll notice immediately is that Rust has stronger compile-time guarantees but [slower compile times](/blog/tips-for-faster-rust-compile-times/).
6767
Most developers find this worthwhile because the borrow checker catches so many issues that would otherwise surface in production.
6868

69-
{% podcast_quote(id="080f1fca", slug="roc-with-richard-feldman", player="s05e04-roc?t=45:10", attribution="Richard Feldman, Creator of Roc") %}
69+
{% podcast_quote(player="s05e04-roc?t=45:10", attribution="Richard Feldman, Creator of Roc") %}
7070
"I certainly think that the degree to which compile times bother you would depend, sort of obviously, on what you're used to and what you think of as sort of possible or normal. Like if I'm used to Elm and sub-second recompiles and stuff like that, then yeah, I mean, it's going to bother me when I'm waiting 10 seconds to be able to build my thing or to run my tests."
7171
{% end %}
7272

73-
{% podcast_quote(id="34099980", slug="zoo-with-jessie-frazelle", player="s03e05-zoo?t=40:33", attribution="Jessie Frazelle, CEO of Zoo") %}
73+
{% podcast_quote(player="s03e05-zoo?t=40:33", attribution="Jessie Frazelle, CEO of Zoo") %}
7474
"Writing Rust is so much more natural to me that even TypeScript is hard for me to write. I\'m just looking for a match statement, or things where I want to abort a Promise. In Tokio you can abort an async operation; you can\'t do that in TypeScript. That drives me nuts."
7575
{% end %}
7676

@@ -344,7 +344,7 @@ As mentioned, for backend web services, Tokio is the standard choice. It's multi
344344

345345
Rust enforces stronger guarantees than TypeScript through its ownership system and borrow checker. Most developers need a few months to get comfortable with the ownership model and will go through a phase of ["fighting the borrow checker"](https://www.youtube.com/watch?v=ZNFdkTIzdXM). This is normal and temporary. Once it clicks, it becomes one of the things you'll miss most when you go back to other languages. (This and the amazing compiler error messages.) There are ways to [flatten Rust's learning curve](/blog/flattening-rusts-learning-curve/) that can help you get there faster.
346346

347-
{% podcast_quote(id="0e3cbed3", slug="1password-with-andrew-burkhart", player="s04e06-1password?t=53:08", attribution="Andrew Burkhart, Senior Rust Engineer at 1Password") %}
347+
{% podcast_quote(player="s04e06-1password?t=53:08", attribution="Andrew Burkhart, Senior Rust Engineer at 1Password") %}
348348
"I had never touched memory coming from TypeScript. I could not get through the Rust code at first, but luckily they hired me anyway. Everything I know about Rust I\'ve learned in the last three years. It\'s definitely something you can pick up. The hardest thing to get from zero to productive isn\'t the syntax: good Rust requires a bit of engineering knowledge the book doesn\'t always cover."
349349
{% end %}
350350

@@ -411,7 +411,7 @@ You won't deal with `null` or `undefined` errors, but you will end up modeling a
411411

412412
NPM gives you more packages, but Rust's ecosystem is of excellent quality and growing rapidly.
413413

414-
{% podcast_quote(id="7e84c99d", slug="radar-with-jeff-kao", player="s05e08-radar?t=08:55", attribution="Jeff Kao, Staff Engineer at Radar") %}
414+
{% podcast_quote(player="s05e08-radar?t=08:55", attribution="Jeff Kao, Staff Engineer at Radar") %}
415415
"Rust really feels modern. There\'s a rich cargo crate ecosystem, a formatter, flame graphs, and the paradigms are very functional, but you\'re not forced to use them. Having a rich data structure ecosystem in the standard library, being able to process vectors with all the functions that many developers are used to these days, really felt refreshing. Especially for a team with largely a background in TypeScript."
416416
{% end %}
417417

@@ -560,13 +560,13 @@ This gives you a clean separation and lets you migrate gradually.
560560

561561
A common pattern is a Rust backend with a TypeScript frontend connected through a typed API layer. The [`ts-rs`](https://github.com/Aleph-Alpha/ts-rs) crate can automatically generate TypeScript types from your Rust types, giving you closed-loop type safety across both sides with almost no extra work:
562562

563-
{% podcast_quote(id="8087b1dc", slug="rust-in-production-ep-9-amp-s-carter-schultz", player="s02e02-amp?t=48:58", attribution="Carter Schultz, Robotics Architect at AMP") %}
563+
{% podcast_quote(player="s02e02-amp?t=48:58", attribution="Carter Schultz, Robotics Architect at AMP") %}
564564
"We have a Rust backend and TypeScript frontend. There\'s an amazing crate, `ts-rs`, that for any Rust types you define will generate TypeScript types for them, so you have closed-loop type safety between them. We end up using `serde_json` to serialize a Rust type, send it to the frontend, and the frontend uses `ts-rs` to get TypeScript types for it. We have closed-loop type safety across both applications for practically free. It was so easy to set up."
565565
{% end %}
566566

567567
Oxide Computer takes this further with a fully generated API layer: their server framework [Dropshot](https://github.com/oxidecomputer/dropshot) generates an OpenAPI spec directly from Rust endpoint definitions, which then drives a TypeScript client generator. No need to write or maintain API definitions by hand:
568568

569-
{% podcast_quote(id="97aa1056", slug="oxide-s-steve-klabnik", player="s03e03-oxide?t=1:23:42", attribution="Steve Klabnik, Author and Software Engineer at Oxide Computer") %}
569+
{% podcast_quote(player="s03e03-oxide?t=1:23:42", attribution="Steve Klabnik, Author and Software Engineer at Oxide Computer") %}
570570
"I write my server-side definition, say \'please generate stuff and regenerate the client in TypeScript,\' and when I switch back to my TypeScript file it gives me a type error if I\'m not passing something correctly. I get full type safety the whole way up through the stack. We\'ve been very happy with TypeScript. It\'s a pragmatic decision to engage with that ecosystem deeply, and it\'s been very, very nice."
571571
{% end %}
572572

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,49 @@
1-
{% set ep_parts = player | split(pat="?t=") %} {% set ep = ep_parts | nth(n=0)
2-
%} {% set t = ep_parts | nth(n=1) | default(value="") | replace(from="%3A",
3-
to=":") | replace(from="%3a", to=":") %} {% set attr_parts = attribution |
4-
split(pat=", ", limit=2) %} {% set author = attr_parts | nth(n=0) %} {% set role
5-
= attr_parts | nth(n=1) | default(value="") %} {% set season_num = ep |
6-
split(pat="e") | nth(n=0) | replace(from="s", to="") %} {% set ep_num = ep |
7-
split(pat="-") | nth(n=0) | split(pat="e") | nth(n=1) %} {% set link_url =
8-
"/podcast/" ~ ep %} {% if t %}{% set link_url = link_url ~ "?t=" ~ t | urlencode
9-
%}{% endif %}
1+
{% set ep_parts = player | split(pat="?t=") %}
2+
{% set ep = ep_parts | nth(n=0) %}
3+
{% set t = ep_parts | nth(n=1) | default(value="") | replace(from="%3A", to=":") | replace(from="%3a", to=":") %}
4+
5+
{% set attr_parts = attribution | split(pat=", ", limit=2) %}
6+
{% set author = attr_parts | nth(n=0) %}
7+
{% set role = attr_parts | nth(n=1) | default(value="") %}
8+
9+
{% set season_num = ep | split(pat="e") | nth(n=0) | replace(from="s", to="") %}
10+
{% set ep_num = ep | split(pat="-") | nth(n=0) | split(pat="e") | nth(n=1) %}
11+
12+
{% set link_url = "/podcast/" ~ ep %}
13+
{% if t %}{% set link_url = link_url ~ "?t=" ~ t | urlencode %}{% endif %}
14+
15+
{% set ep_content = load_data(path="content/podcast/" ~ ep ~ "/index.md", format="plain") %}
16+
{% set id = ep_content | split(pat="letscast-player-") | nth(n=1) | split(pat='"') | nth(n=0) %}
17+
{% set slug = ep_content | split(pat="/episodes/") | nth(n=1) | split(pat="/") | nth(n=0) %}
1018

1119
<blockquote>
1220
{{ body | markdown() | safe }}
1321
<p>
14-
&mdash; <a href="{{ link_url }}">{{ author }}</a>{% if role %}, {{ role
15-
}}{% endif %} (<a href="{{ link_url }}"
16-
>Rust in Production, S{{ season_num }}E{{ ep_num }}</a
17-
>)
22+
&mdash; <a href="{{ link_url }}">{{ author }}</a>{% if role %}, {{ role }}{% endif %} (<a href="{{ link_url }}">Rust in Production, S{{ season_num }}E{{ ep_num }}</a>)
1823
</p>
1924
</blockquote>
2025
<div>
2126
{% if t %}
2227
<script>
2328
window.pO = window.pO || {};
24-
window.pO["#player-{{ id }}"] =
25-
"{{ t }}"
26-
.split(":")
27-
.reverse()
28-
.reduce((a, v, i) => a + (parseInt(v) || 0) * 60 ** i, 0) *
29-
1000;
30-
if (!window.pH) {
31-
window.pH = 1;
32-
let o;
33-
const h = (f) => {
34-
if (f && f._h) return f;
35-
let r = (s, e, c) => {
29+
window.pO['#player-{{ id }}'] = "{{ t }}".split(':').reverse().reduce((a,v,i)=>a+(parseInt(v)||0)*60**i,0)*1000;
30+
if(!window.pH){
31+
window.pH=1; let o;
32+
const h = f => {
33+
if(f&&f._h) return f;
34+
let r = (s,e,c) => {
3635
let t = window.pO[s];
37-
if (t) {
38-
c.sharePlaytime = false;
39-
c.playtime = t;
40-
}
41-
let p = f(s, e, c);
42-
if (t)
43-
p.then((x) =>
44-
x.dispatch({
45-
type: "REQUEST_PLAYTIME",
46-
payload: t,
47-
}),
48-
);
36+
if(t) { c.sharePlaytime=false; c.playtime=t; }
37+
let p = f(s,e,c);
38+
if(t) p.then(x => x.dispatch({type:'REQUEST_PLAYTIME', payload:t}));
4939
return p;
5040
};
51-
r._h = 1;
52-
return r;
41+
r._h=1; return r;
5342
};
54-
if (typeof podlovePlayer == "function")
55-
window.podlovePlayer = h(podlovePlayer);
56-
else
57-
Object.defineProperty(window, "podlovePlayer", {
58-
get: () => o,
59-
set: (v) => (o = h(v)),
60-
configurable: true,
61-
});
43+
if(typeof podlovePlayer=='function') window.podlovePlayer=h(podlovePlayer);
44+
else Object.defineProperty(window,'podlovePlayer',{get:()=>o, set:v=>o=h(v), configurable:true});
6245
}
6346
</script>
6447
{% endif %}
65-
<script
66-
id="letscast-player-{{ id }}"
67-
src="https://letscast.fm/podcasts/rust-in-production-82281512/episodes/{{ slug }}/player.js?size=s"
68-
></script>
48+
<script id="letscast-player-{{ id }}" src="https://letscast.fm/podcasts/rust-in-production-82281512/episodes/{{ slug }}/player.js?size=s"></script>
6949
</div>

0 commit comments

Comments
 (0)