►
From YouTube: Bay Area Rust Meetup @ Cloudflare December 3, 2019
Description
00:00:00-00:06:00 Steve Pack: Intro to Cloudflare
00:06:25-00:50:30 Raph Levien: Declarative UI Patterns in Rust
00:56:50-01:19:19 Gabbi Fisher: CLIs in Rust
A
B
All
right,
everybody,
let's
get
started,
welcome
to
the
Bay
Area
Russ
made-up
hosted
at
CloudFlare.
Thank
you
all
for
coming.
Thank
you
to
Mozilla
for
co-hosting
this
with
us
and
allowing
us
to
host.
If
any
of
you
are
interested
in
speaking,
then
please
just
get
in
contact.
Probably
the
easiest
way
is
on
the
meetup.
Comm
group
just
comment
message
me
message:
Manish,
either
of
us
will
see
it
always
looking
for
new
speakers.
B
We're
gonna
have
two
talks
tonight,
one
from
Iraq
on
declarative,
UI,
Xin,
rusts
and
Gabby
from
CloudFlare
talking
about
rusty
lies,
and
then
there
will
be
some
time
depending
on
how
long
the
talks
go,
possibly
afterwards
for
some
more
chat
and
then,
when
we
cut
off
at
8:30,
there's
a
bar
right
there.
If
folks
want
to
continue
conversation
exits,
follow
the
signs.
B
The
way
you
came
in
on
out
the
back
here
and
the
restrooms
are
just
in
this
corner:
okay,
so
I'm
a
product
manager
at
CloudFlare,
I,
don't
write
code
day-to-day
anymore,
so
I
sort
of
feel
like
I,
have
to
explain
why
I
host
this-
and
this
is
where
you
earn
your
pizza
by
the
way.
So
apologies,
but
you
have
to
listen
to
me
for
five
minutes.
B
One
of
the
things
is
that
we're
always
hiring
and
we've
had
some
really
good
hires
through
the
Russ
meetups,
regardless
of
whether
they're
for
rust
rolls
or
not
so
two
teams
that
are
actively
hiring
at
the
moment.
Rajesh
is
hiring
for
an
application
services
engineer.
Tech
stack
is
mostly
golang.
Kafka
react,
Postgres
and
a
little
bit
of
MySQL
and
more
recently
cadence
if
anyone's
into
workflow
management
engines.
B
Aki
is
hiring
a
Content
platform
engineer
on
the
cache
team.
A
really
interesting
thing
about
that
team.
That's
essentially
the
CDN
that
you
will
sort
of
you
know
probably
came
to
know
CloudFlare
at
some
point.
So
when
we're
processing
the
and
what
we're
up
to
like
1
point,
something
million
requests
a
second
it.
It
often
is
going
through
that.
So,
if
you
want
your
code
to
be
some
of
the
most
sort
of
executed
code
in
the
world,
that's
a
good
team
to
join.
B
They
do
a
lot
of
things,
a
lot
of
lure
actually
but
they're
sort
of
looking
at
how
much
of
that
they
can
replace
with
rust
right
now.
So
for
the
sort
of
hardcore
our
stations
among
you,
that's
an
interesting
one-
Aki's
not
here,
but
talk
to
me
if
you're
interested,
no,
it's
email
take
a
pic
show
so
quickly.
B
Cloudflare
gets
in
front
and
we're
able
to
protect
sites
by
dropping
all
of
that
traffic
at
the
edge
only
sending
good
traffic
to
your
site.
That's
one
of
the
the
biggest
ways
we
became
known.
I
already
mentioned
the
CDN
I'm
sure.
Most
of
you
understand
like
how
that
works.
But
you
know
in
the
one
line
we
have
servers
close
to
every
user
in
the
world.
B
So
if
you
cash
your
content
with
us,
your
site
will
perform
much
faster
if
you're
in
Sydney,
requesting
a
resource
from
New,
York
you'll
get
it
from
Sydney,
won't
get
it
from
you.
That's
how
we
came
to
be
known,
but
we're
doing
a
lot
more
now
than
just
those
traditional
products
and
one
of
the
one
I
think
of
interest
to
this
community
is
workers
and
workers.
B
Instead
of
us
just
running
our
code
in
these
200
cities
or
close
to
200
cities
around
the
world,
that
we
have
data
centers,
you
can
now
run
your
code.
You
can
do
that
by
writing
JavaScript
and
will
will
automatically
deploy
it
and
run
it
for
you
or
actually
any
wisdom
compatible
language,
including
rusts.
So
if
you
want
to
write
an
API
interrupt
runs
on
the
edge,
you
can
do
that
today
and
there's
lots
of
things
that
these
are
used
for
at
the
moment.
B
You
can
see
some
examples,
they're
about
like
security,
running
complex
business
logic,
but
something
I
think
that
gets
missed
sometimes,
is
that
workers
also
has
a
kV.
Okay,
key
value
store,
it's
basically
an
eventually
consistent
key
value
store.
So
you,
if
you
can,
if
your
app,
can
work
without
a
transactional
database
but
and
eventually
consistent
kV,
so
you
can
run
the
whole
thing
on
the
edge.
Not
all
apps
work
like
that.
B
Workers
sites
means
that
you
can,
if
you
have
a
any
type
of
UI,
I've
written
any
sort
language,
that's
just
static
files.
You
can
deploy
that
to
workers
and
we
will
serve
it
for
you,
so
you
can
now
run
entire
websites,
entire
sort
of
business
logic
and
with
the
datastore
all
three
workers
without
having
to
worry
about
origin
service,
you
don't
have
to
go
turn
up
some
ec2
instance
or
anything
like
that.
You
can
just
deploy
and
we
will
take
care
of
it
all.
B
This
is
my
latest
side
project
shameless
plug,
but
it's
just
an
example
of
like
a
view,
pjs
app
with
like
some
logic
and
it'll,
send
you
a
page
of
a
book
every
day,
just
an
example
of
what
you
can
do
with
workers
workers
sites
and
workers.
Kv,
ok,
pizza
earned
black
to
welcome
to
the
stage
raft
talk
about
debt.
Clarity
of
you
is
in
rust,
thanks.
C
C
Right,
well,
click
present,
hopefully
yeah
thanks
so
much
for
being
here.
It
is
my
pleasure,
thanks
to
CloudFlare
for
hosting
this
and
I'm
gonna
talk
to
you
about
declarative
UI
patterns
in
rust
and
I.
Think
my
motivation
in
a
lot
of
this
work
is:
can
we
build
a
UI
that
leverages
rust
straits?
It's
pretty
easy
to
imagine
building
you
eyes
that
don't
like,
for
example,
of
using
FFI
to
wrap
some
existing
UI
toolkit,
but
is
it
possible
to
build
a
UI
that
has
rests
performance
safety,
cross-platform
compatibility
and
can
leverage?
C
C
It's
a
lot
of
different
moving
parts
that
all
have
to
come
together
and
you
know
there's
drawing
there's
animation,
there's
text
handling,
which
is
you
know,
really
difficult
today,
I'm
going
to
talk
very
I'm,
gonna
kind
of
focus
in
on
this
problem
of
reactivity,
and
you
can
kind
of
define
reactivity
as
making
this
kind
of
code
work.
You
know
that
you
want
to
write
your
UI
logic
in
a
way
that
isn't
dealing
with.
You
know:
callback,
handlers
that
have
to
be
wired
up
and
so
on
and
so
forth.
C
That
is
written
in
this
kind
of
very
straightforward.
You
know:
here's
my
app
state,
here's
how
the
app
state
gets
presented
to
the
views
and
here's
how
the
interaction
changes
the
app
state,
and
so,
if
you
that's
in
contrast
to
like
a
more
traditional
object-oriented
style
where
you've
got
objects
that
represent
the
widgets
and
then
you've
got
to
do
all
this
wiring
up
of
the
handlers
and
so
on
and
so
forth.
C
To
make
that
work,
and,
of
course
this
is
a
perfectly
good
way
to
make
UI
there's
a
lot
of
successful
you
why
that's
written
in
the
object-oriented
style,
but
already
we
can
see
some
of
the
problem.
There's
duplication
of
logic
here
that
we've
got
we're
having
to
set
up
this
count
in
both
the
set
up.
C
The
real
motivation
that
I
have
for
kind
of
exploring
these
reactive
techniques
is
that
translating
that
object-oriented
style
to
rust
leads
to
bad
Nydia,
Matic
rust
code,
and
you
can
see
this
is
the
kind
of
thing
you
have
to
do.
This
isn't
real
code,
but
it's
it's
kind
of
a
good
model
of
it
that
you
have
to
wrap
all
of
your
state
in
ref
cell,
because
the
the
state
that
button
count
or
whatever
is
being
shared
between
the
widget.
C
That's
showing
it
and
the
handlers
that
have
to
somehow
get
a
reference
to
that,
so
they
can
update
that
state
and
that
shared
ownership
creates
all
kinds
of
problems.
When
you
do
a
borrow
on
this
ref
cell,
that
could
fail.
That
could
be
like
if
it's,
if
you
know,
as
your
paths
through
the
code,
get
more
complex
that
could
already
be
borrowed,
so
that
would
be
a
panic
or
if
you
were
using
mutex
instead
of
ref
cells.
So
this
would
be
Fred
safe
code.
C
Then
that
would
be
a
that
would
be
a
deadlock,
and
so
we
really
don't
want
to
have
runtime
failures.
We
want
to
have
the
logic
encoded
at
compile
time
so
that
you
know
that
it's
just
work,
so
it
should
be
pretty
easy
to
just
do
declarative
UI,
we'll
just
go
out
there
and
see
what
the
standard
UI
you
know.
Kind
of
paradigm
is
for
building
this
reactive
stuff
and
we'll
just
translate
that
to
rust
so
I
started.
You
know,
like
I've,
been
following
this
for
a
while,
but
like
in
preparation
for
this
talk.
C
Actually
I
was
going
through
all
of
these
different
choices.
You
know
there's
like
this
huge
perf,
you
there's
a
ton
of
stuff
written
in
JavaScript
and
then
there's
also
a
lot
of
other
interesting
things
in
other
languages
and
I
was
trying
to
round
my
head
around
it
and
really
finding
it
difficult
and
I.
Think
I
have
like
steps
towards
a
theory
that
unifies
that
I'm
not
gonna,
go
into
it
in
a
lot
of
detail
tonight,
because
that
would
be
a
whole
talk
in
and
of
itself.
A
C
I
recommend
checking
that
out.
So
the
kind
of
central
thesis
of
that
blog
post
is
that
reactive
UI
can
be
modeled
as
a
transformation.
A
series
of
a
pipeline
of
transformations
of
trees,
so
you're
modeling,
your
application
state
is
a
tree.
You're
modeling,
your
widgets
is
a
tree.
You've
got
your
layout
as
annotations
to
that
tree.
You've
got
draw
objects
that
you're
generating
you
know,
that's
not
actually
the
end
of
the
pipeline.
C
So
again,
looking
at
this
sort
of
running
example-
and
this
is
by
the
way
not
supposed
to
be
any
particular
language-
it
might
be
familiar
to
some
people,
but
this
is
kind
of
pseudocode
representing
the
problem.
So
we've
got
you
know
very
simple,
widget
hierarchy.
We've
got
a
stack
with
a
text
and
a
button,
and
we've
got
some
behavior
attached
to
that
button.
So
that's
gonna
mutate
the
state
and
then,
when
that
state
is
mutated,
we
want
magically
the
view
to
that.
That's
displaying
that
count
to
update.
C
So
this
is
kind
of
like
this
is
kind
of
the
statement
of
the
problem
that
there's
that,
in
this
logic,
there's
a
dependency
edge,
but
we
don't
want
to
have
to
specify
that
dependency
edge
explicitly
and
wire
up
all
that
kind
of
propagation.
Of
those
events,
we
want
to
throw
this
at
our
reactive
UI
system
and
then
have
our
reactive
UI
system
play
that
to
the
user.
So
how
do
we
do
that
so
I'm
gonna
kind
of
walk
through
how
druid
does
it
kind
of
show
trying
to
show
not
tell
so?
C
This
is
the
actual
code
that
is
kind
of
the
adaptation
of
that
pseudo
code
into
rest
code,
and
you
can
see
that
it's
a
fairly
straightforward
adaptation
of
the
idea
into
rest
code.
There's
a
little
bit
of
elaboration
and
we've
actually
made
made
the
UI
a
little
bit
nicer
that
we've
centered
and
added
some
padding
and
so
on
and
so
forth.
But
the
structure
is
there,
so
we've
got
one
struct
that
holds
the
state
and
then
we've
got
another
function
that
builds
the
UI
builds
a
widget
tree
and
then
on
that
widget
tree.
C
A
lot
of
the
behavior
that
we
want
is
specified
in
closures
and
those
closures
are
pretty
straightforward.
They
just
directly
get
a
reference
to
the
state
and
then
are
able
to
access
that
state
and
mutate
that
state.
So
when
you
click
the
button,
you
know
it
just
it
just
increments.
A
field
in
that
struck
so
actually
I.
C
That's
that's
kind
of
half
of
the
app,
and
this
is
the
other
half
yeah
and
cool
part
of
this
is
that
on
these
two
slides?
That's
all
you
need,
in
your
main
dot
RS
in
order
to
get
a
UI
and
there's
a
couple
of
interesting
things
about
this.
One
of
them
is
that
we're
actually
creating
the
initial
state
so
that
it's
not
as
clear
because
data
has
a
AppData
has
type
appstate,
so
we're
actually
creating
that
app
state
and
then,
when
we're
passing
that
into
the
app
launcher,
we're
passing
in
that
function.
C
That
creates
the
widget
tree
and
we're
passing
in
the
state.
And
then
after
we
passed
that
in
then
the
kind
of
UI
system
owns
those
pieces
of
state
and
to
show
that
I'm
not
lying.
This
is
the
same
code.
That's
the
same
same
stuff,
I,
just
loaded
it
onto
steeps
computer.
He
was
able
he
was
kind
enough
to.
Let
me
borrow
it
and
then
what
we'll
do
is
that
we
will
do
this.
That
will
do
cargo
run
on
that
code,
and
here
we
have
a
piece
of
UI
that
implements
that
so
magic.
C
Reflected
in
the
operation
in
this
program,
so
when
we,
when
we
create
that
widget
tree
we're
getting
the
widget
tree
on
the
right
and
then
we
have
the
data,
which
is
a
separate
structure.
That's
kind
of
one
of
the
key
things
here
that
the
application
data
and
the
widget
tree
are
two
different
structures.
And
so
it's
gonna
create
this
structure.
And
what
is
there
more
to
say
about
that?
So
then,
when
we
start
running
it,
I'm
gonna
kind
of
trace
through
the
steps
of
clicking
on
that
button.
C
The
event
comes
in
it
gets
dispatched
and
to
dispatch
that
to
know
that
you
clicked
on
the
button,
you
actually
need
the
geometry
at
that
point.
The
geometry
is
also
stored
in
those
widget
pod
structures,
but
I'm
not
showing
that
you
can
assume
that
that
happens.
My
magic
so
event
gets
dispatched.
It
goes
down
to
the
button
and
then
the
button
might
do
some
stuff.
C
It
might
update
its
own
stage
to
show
that
it's
been
clicked,
but
the
thing
that
we
care
about
here
is
that
it's
gonna
run
that
closure,
so
that
that
button
owns
that
closure
and
the
closure
says
s
count
+
equals
1.
So
when
it
runs
that
closure,
it
has
a
mutable
reference
to
the
app
state
and
it
just
goes
ahead
and
increments
that
state.
So
now
that
count
is
1.
So
that's
the
event
propagation
phase.
This
happens
in
phases.
There's
four
phases
I'll
go
into
that
the
event
phase
is
kind
of
the
first.
C
The
second
phase
is
the
update
pass
and
what
that's
mostly
doing
is
state
different.
So
dipping
is
one
of
the
kind
of
major
categories
of
how
you
make
these
reactive
systems
work.
That
you've
got
old
state
you've
got
new
state,
you
compute
some
diff
between
those
two
states,
and
then
that
tells
you
what
you
need
to
change.
I
tells
you
need
what
you
need
to
update
in
the
appearance
in
the
window,
so
we're
gonna
run
through
this
and
we're
going
to
do
this
state
dipping
and
the
old
state
was
zero.
C
So
that's
not
the
same
as
the
state.
That's
that's
there
now,
so
we're
gonna
go
ahead
and
update
that
and
then
we're
gonna
do
that
same
kind
of
traversal
through
this
widget
tree
and
when
we
get
down
to
the
Dynel.
That's
a
label,
that's
dynamic,
so
the
string
is
not
a
constant.
It's
actually
run
by
a
closure.
Then,
when
that
gets
an
update,
it's
gonna
run
that
closure
and
it's
gonna
get
a
string
back
and
it's
gonna
say:
oh,
that
string
that
I
got
back
is
not
the
same
as
the
old
string.
C
C
C
So
the
the
dipping
is
kind
of
the
heart
of
this
thing:
you're
dipping
the
old
app
state
to
the
new
ant
State,
and
so
that
better
be
efficient
like
if
you're
gonna
run
through.
You
know
megabytes
of
complex
application
state.
Then
you
might
not
be
able
to
achieve
interactive
performance.
So
to
do
this,
we
kind
of
encourage
the
app
state
to
be
written
in
a
particular
way.
We
want
it
so
that
you
can
test
whether
something
is
changed
with
simple
pointer
equality.
So
we
have
this
data
trait,
which
has
one
method.
C
It's
really
looks
a
lot
like
partial
EQ,
but
it's
different,
partial
EQ,
we'll
do
a
deep
dish.
We
don't
do
that.
We
do
a
shallow
comparison.
So
if
it's
an
arc
for
example,
then
we
just
look
at
the
pointer
and
see
has
the
pointer
change.
So
it's
a
super
quick
test
to
do,
and
so
it's
an
approximate
equal
that
it
might
say.
No,
it
might
say
no.
C
This
is
this
is
different
and
that's
okay,
because
then,
if
that
happens,
then
you
just
run
through
it
and
then
you
know
go
a
little
deeper
into
the
widget
tree
with
it.
So
this
would
be
pretty
annoying
if
you
had
to
implement
it
yourself.
So
we
have
a
proc
macro
that
derives
it
for
simple
structs,
there's
a
if
you
do
wrap
more
complex
state.
C
C
So
this
business
of
traversing,
the
widget
hierarchy
and
propagating
appstate
change.
If
we
do
this
the
simple
way,
then
every
time
the
app
state
changes,
then
we're
gonna
be
propagating
those
changes
down
the
entire
widget
tree
and
that
might
be
slower
that
might
not
be
efficient,
and
so
the
solution
that
we
came
up
with
to
this
problem
is
lenses
and
lenses
are
an
idea
from
Haskell
they're,
probably
predate
Haskell,
but
they're.
C
Certainly
popularized
in
Haskell
they're,
now
considered
kind
of
a
one
of
the
key
pieces
of
developing
things
in
Haskell,
where
you
need
structs,
where
you
need
this
kind
of
tree
structure
of
the
data
and
the
idea
of
lensing
is
that
your
widget
tree,
not
every
widget,
has
a
reference
to
the
root
of
the
app
state
that
it
might
have
a
reference
to
some
piece
of
the
app
state.
So
if
you
have
like
a
kind
of
a
typical
to-do
list,
then
your
list
might
be
getting
that
sort
of
arc
avec
of
to-do
item.
C
And
then,
when
you
go
into
the
individual
to-do
item,
you're
gonna
have
that
state.
And
then
you
know
at
the
bottom
of
the
tree.
Maybe
you're
gonna
have
a
string
and
what
the
lens
does
is
that
it
kind
of
changes,
the
focus
so
that,
as
you
traverse
into
this
you're,
not
looking
at
the
whole
app
state
but
you're,
looking
at
a
small
part
of
the
app
State.
So
how
does
that
look
like
in
code?
A
simple
way
to
do?
This
would
just
be
that
you
have
essentially
getter
and
a
setter.
C
So
you
know
you
have
something
that
returns
a
reference
to
the
field.
If
you,
if
you
look
at,
if
you
were
going
to
implement
a
lens
for
that
count,
then
you
could
just
return
a
reference
to
the
count
and
the
same
for
a
mutable
reference.
It
turns
out.
We
don't
actually
do
it
this
way.
The
actual
tree
is
kind
of
the
same
idea,
but
instead
of
returning
a
reference
we
take
call
back,
and
then
we
call
the
call
back
with
that
reference,
and
this
just
lets
us
do
more-
that
we
can
synthesize
data.
C
We
can
create
a
pair.
You
can't
return
a
reference
to
a
pair
that
doesn't
exist,
but
you
can
create
a
pair
and
then
generate
that
reference
and
pass
that
reference
into
the
data
and
the
other
thing
that
it
lets
you
do
is.
If
you
want
to
have
some
logic,
you
know
to
do
a
little
deeper
like
what
change
did
it
really
change?
Do
I
really
need
to
propagate
that,
because
this
lends
like
one
of
the
functions
of
this
lens,
is
propagating
the
changes
as
they
happen,
so
using
callbacks
basically
lets
you
lets
these
lenses.
C
Do
more
sophisticated
things,
and
one
of
the
things
like
this
shouldn't
be
surprising,
because
it's
certainly
true
in
Haskell
that
you
can,
you
can
compose
lenses.
You
can
actually
do
data
transformations,
there's
a
lot
that
you
can
do
with
these
lenses.
There's
an
ecosystem
and
you
should
be
able
to
compose
them
in
a
way.
That's
kind
of
similar
to
the
way
that
futures
get
composed.
C
So
lenses
do
two
things
for
us:
they
structure
your
apps
in
a
composable
way,
so
you
can
take
a
piece
you
can
take
a
component
that
knows
how
to
deal
with
some.
You
know
somewhat
complicated
piece
of
data
and
you
can
put
that
into
your
app
just
by
lensing
down
to
that
data
type,
and
the
hope
is
that
this
will
be
a
kind
of
a
powerful
way
of
composing
UI
out
of
smaller
pieces,
and
the
other
thing
that
it
does.
Is
it
kind
of
answers
that
an
original
question
of
how
are
we
encoding
these
dependencies?
C
C
So
we're
kind
of
discovering
we're
kind
of
inventing
and
discovering
as
we
go
and
one
of
the
things
that
we
find
is
that
not
every
piece
of
inner
action
fits
very
nicely
into
this
kind
of
functional
programming
style,
declarative
pipeline.
You
need
other
ways
of
making
things
happen
in
the
app,
and
so
the
main
thing
that
we
have
right
now
is
this
thing
called
command
and
a
command.
It's
gonna
be
pretty
similar,
pretty
familiar
to
people
who
have
done
cocoa
programming,
but
it's
a
selector
and
then
an
optional
payload.
C
And
you
know
the
kind
of
thing
that
happens
in
commands
is
that
if
you
have
a
menu,
then
that
generates
a
command
and
that
gets
sent
to
your
app,
and
it's
also
used
to
do
things
like
open
and
close
windows.
Pull
up
a
right-click
context,
menu
show
a
file
dialog
the
result
of
that
file.
Dialog
is
delivered
as
a
command.
This
is
all
happening
with
commands,
and
you
know
we're
looking
at
like
ways
to
make
this
even
richer.
C
So
we're
gonna
go
beyond
just
that
out
state
to
widget,
which
is
kind
of
the
update
phase
or
the
update
method
of
the
widget
trait.
It
actually
encapsulates
a
lot
of
different
kinds
of
behavior,
so
there's
event
processing.
You
know
how
do
you
handle
mouse
clicks,
keyboard
events,
all
those
things
that
happen
that
effect
to
the
app
there's,
the
update
phase,
which
kind
of
goes
from
out
state
to
widgets,
there's
the
layout
phase,
which
computes
that
layout
geometry
as
an
annotation
and
then
there's
a
paint
phase
which
renders
those
that
appearance.
C
So
that
is
visible
on
the
screen
and
that's
really
reflected
in
the
code
the
that
this
isn't
the
whole
thing,
but
it's
yeah.
It
gives
you
a
pretty
good
idea
of.
What's
going
on
that,
there's
those
four
basic
methods
in
the
widget
tray
that
encode
those
four
different
phases-
those
four
different
transformations
from
one
tree
to
another,
and
we
have
an
ownership
model
which
is
extremely
tree-based
and
actually,
if
you
were
here
or
the
it
was
at
Mozilla
about
a
year
and
a
half
ago,
I
gave
a
talk
and
there
was
a
graph.
C
C
So
now
we
have
this
tree
ownership
model,
which
basically
says:
if
you
have
a
container,
it
simply
owns
all
of
its
children.
So
all
that
stuff,
where
you
needed
to
have
references
you
know
to
update
the
state.
This
all
happens
by
traversing
down
from
the
top
of
the
tree
and
then
into
the
individual
widgets.
In
order
to
get
that
behavior
implemented,
so
those
is
kind
of
nice,
because
this
is
a
trade
object,
it
can
own
its
own
local
state,
that's
something
that
is
sometimes
tricky,
and
these
reactive
systems
are
in
in
GUI,
immediate
mode
GUI.
C
How
do
you
get
your
own
local
state
and
in
this
system
it's
pretty
simple
you
just?
It
can
just
be
a
part
of
the
object
that
impulse
the
widget
trade
and
then
it
doesn't
own
the
app
state,
but
it
has
access
to
it
through
references
and
those
are
mutable
references
in
the
case
of
the
event
and
they're
immutable
references,
so
you're
encoding
in
the
type
system.
You
can't
just
change
the
app
State
in
the
middle
of
a
paint
can't
do
that.
C
You
can
in
a
lot
of
other
sort
of
programming
languages
besides
rust,
so
we're
also
hoping
that
this
is
a
the
kind
of
encapsulating
all
of
the
behavior,
the
event,
processing
and
the
reactive
stuff
and
the
rendering
will
make
it
so
that
it's
easier
to
compose
you
don't
need
to
have
a
lot
of
wiring
that
you
can
just
kind
of
make
a
tree
out
of
these
and
you
you
can
you
know
widget
can
own
pieces.
C
And
then
this
thing
where
all
traversal
start
from
the
root
I
think
that's
really
key
to
the
druid
architecture,
because
that
simplifies
things
so
a
lot
of
the
other
reactive
systems
like,
for
example,
if
you
look
at
jet
pack
composed
very
well-engineered
system,
but
it
has
this
recompose
mechanic
in
it,
where
you
can
kind
of
jump
into
the
middle
of
the
tree
and
say
I
only
want
to
recompute
this
part
of
it
and
I
mean.
Obviously
they
have
good
reasons
for
doing
that.
C
But
I
think
it
increases
the
complexity
dramatically,
so
this
is
one
way
we're
able
to
simplify
and
the
way
that
traversals
work
from
the
route
route.
It's
kind
of
similar
to
the
way
futures
work
under
the
hood
as
well.
There's
a
you
know.
This
is
an
idiom
that
works
well
in
rust
and
that's
what
we're
trying
to
do.
C
So
all
of
this
is
work
in
progress.
It's
not
done
it's
kind
of
obvious.
We
need
more
widgets.
There's
a
lot
more
to
be
done.
We
have
a
really
robust
community.
We
have
a
lot
of
people.
It
seems
like
almost
every
day,
like
somebody
showed
up
today
and
said:
I
want
to
build
a
tab.
You
know
the
view
with
the
tabs
and
I'm
like
that
sounds
great.
C
Let's
do
it
it's
kind
of
hard,
but
let's
do
it,
but
there's
other
pieces
to
like
you
know,
building
these
lends
common
aiders
building
this
kind
of
ecosystem,
the
same
way
that
it
exists
in
the
Haskell
world
and
we
want
to
explore.
We
haven't
we've
done
a
little
bit
of
data
transformation,
simple
stuff,
but
we
want
to
like
what
kinds
of
interesting
UI
behavior.
Can
you
express,
as
these
lens
Combinator's
and
we're
still
discovering
the
patterns
that
we
need
to
build
real
apps
out
of
these
pieces?
C
It's
not
obvious
if
you
know
how
to
build
something
in
a
traditional
object-oriented
framework,
then
a
lot
of
the
things
that
you
expect
are
just
not
there
or
they're
kind
of
in
different
places.
So
it
takes
a
little
bit
of
effort
to
figure
out
how
to
structure
a
real
app
in
this
kind
of
reactive
architecture
and
again,
I
think
that
we
can
look,
there's
a
lot
of
really
excellent
work
from
the
functional
programming
world
and
that,
like
these
immutable
data
structures,
for
example
and
I,
think
a
lot
of
that
will
adapt
very
nicely
into
rust.
C
So
in
the
longer
term,
I
want
Druid
to
be
a
general-purpose
UI
toolkit
I
want
it
to
be
something.
People
can
pick
up,
build
cross-platform
UI,
get
that
performance
in
the
meantime,
we're
driving
the
development
by
trying
to
build
one
real
app,
and
that
is
a
font,
editor
called
ruin.
Bender
and
interestingly
enough,
most
of
the
code
is
written
by
Cullen
roffels,
who
is
also
a
major
contributor
to
druid,
and
you
might
recognize
his
name.
C
He
was
one
of
the
major
people
on
zai,
editor
and
I'll,
actually
give
you
a
little
demo,
so
I
again
just
install
that,
while
waiting
for
pizza-
and
here
we
go
and
so
then
a
couple
interesting
things,
it
has
a
sort
of
a
reactive
layout.
You
know
flow
based
layout.
It
passes
the
smooth
resize
test.
If
you
read
that
blog
and
then
we
can
go
in,
and
you
know
pick
a
nice
glyph
that
we
like
move
things
around,
there's
a
couple
of
different
tools.
C
You
can
use
the
pen
tool
draw
ups,
it's
not
exactly
what
I
wanted
to
have
happened
so
well,
its
undo.
Does
that
works
too?
All
right,
excellent
and
you
can
see
like
these
menus
up
here.
These
are
Mac
native
menus,
and
so
it's
still
early
days
but
I'm
encouraged
I
feel
like
we're
on
track
to
building
a
real
app.
And
hopefully
you
know
something
that
really
exercises
the
ideas.
C
So
there's
some
open
questions
like
yeah
I,
hope,
I've
made
the
case.
I
hope,
I've,
explained
and
said.
This
is
a
reactive
system.
That's
in
rust
meets
the
rest
language
where
it
is,
but
I
it's
certainly
not
the
only
one
there's
moxie
adam
is
here.
We
can
I
was
kind
of
hoping
that
we
have
some
sort
of
like
you
know,
Babel
or
something
that
didn't
have
enough
time
didn't
have
time
to
prepare
for
that.
So,
but
Moxie
is
another
very
interesting
system
and
it
has
a
lot.
C
It
there's
some
of
the
ideas
that
are
very
recognizably
the
same
and
there's
some
things
that
it
does.
That
are
very,
very
different,
and
so
that's
a
really
interesting
question
there's
make
pad,
which
is
out
of
Amsterdam
and
is
not
on
enough
people's
radar.
It's
a
really
impressive
system.
People
who
are
interested
in
GUI
and
rust
should
really
be
looking
at
me
ad.
It
is
more
inspired
by
in
GUI
ideas
and
so
again
a
very
different
set
of
trade-offs
and
I,
really
like
I.
C
Think
one
of
the
interesting
things
to
happen
over
the
next
few
months
is,
let's
start
playing
with
these
systems
seriously.
Let's
collect
evidence
about
what
works
well
and
what
doesn't
work
well
and
then
the
parts
that
don't
work
well,
let's
learn
from
that,
and
you
know
I've
certainly
been
learning
from
these
other
rust.
Gui
efforts
and
I
certainly
hope
that
they're
they're
learning
from
the
druid
work
as
well.
One
of
the
questions
that
I
haven't
addressed
is
what
could
you
do
if
the
language
was
not
a
constant?
That
was
a
variable.
C
What
could
you
do
if
you
could
add
features
to
the
language
and
if
you
look
at
a
lot
of
the
other
reactive
systems
that
are
out
there
like,
for
example,
spell
and
jetpack
compose,
will
both
take
your
code
and
do
a
static
analysis
of
the
code
and
use
that
to
extract
that
fine-grained
dependency
graph?
So
now
you're
not
expressing
it
explicitly
at
all,
it's
being
it's
being
extracted
from
the
code
and
in
order
to
run
the
code
you
aesthetic
it.
C
C
So
this
is
a
journey
and
we
have
a
really
robust
community
I'm,
not
sure
I
want
to
invite
like
a
lot
more
people.
I,
certainly
don't
want
to
create
the
the
false
impression
that
druid
is
ready
to
use
right
now.
If
you
want
to
build
a
UI,
then
druid
is
not
the
toolkit
for
you.
If
you
want
to
learn
how
you
eyes
are
built,
then
drew
it
is
a
pretty
appealing
project,
and
so
we've
got
the
code
on
github.
We
have
a
discussion
channel.
C
D
So
one
problem
that
I've
noticed
with
a
number
of
at
least
web-based
reactive
UI
frameworks
is
that
they
struggle
a
lot
when
it
comes
to
very
large
data
sets
and
data
very
large
data
visualization.
Is
there
anything
in
the
design
of
Druid
that
allows
it
to
scale
to
save
millions
of
rows
and
a
table
better
than
say
react,
barring
the
barn,
the
obvious,
and
that
the
DOM
is
a
retain
mode
tree
versus
bris
outdrew?
It
is
using
some
immediate
mode
thing
I'm,
assuming
at
the
end
right.
C
So
I
hope
that
the
answer
to
this
question
is
yes
and
I.
Think
that
we're
testing
it
because
the
fun
editor
that
we're
building
is
really
intended
to
handle
cgk
fonts,
so
you're
gonna
have
hundreds
of
thousands
of
glyphs
and
then
each
glyph
is
going
to
have
outlines
with
dozens
of
nodes,
so
you're
going
to
be
dealing
with
millions
and
millions
of
data
elements
in
your
app
State.
C
So
if
we're
not
able
to
handle
that
efficiently,
you're
not
going
to
be
able
to
get
interactive
performance,
so
we're
gonna
test
that
as
we
build
our
in
vendor
now,
in
terms
of
how
do
you
achieve
that,
I
think
again
that
it's
that,
first
of
all,
already
in
the
architecture
there's
this
principle
that
you're
not
traversing
the
widget
tree.
Every
app
update
that
like
when
you
go
into
an
individual
glyph
that
that
lens
is
gonna
say
only
this
glyph
has
changed.
C
C
E
So,
maybe
not
at
like
a
practical
level
immediately,
but
at
a
kind
of
conceptual
level.
Is
there
a
similarity
between
the
kind
of
techniques
that
you
described
for
doing
kind
of,
like
partial
state,
traversals
for
updates
and
techniques
for
situations
where
actually
somebody's
application
only
has
a
small
piece
of
some
like
global
distributed
state
so,
for
instance,
like
something
like
Twitter,
for
instance?
C
So
that's
a
fascinating
problem.
Space
I
mean
we're
we're
very
explicitly
trying
to
limit
our
scope
so
that
we
can
ship
something
so
but
I
think
that
conceptually
there
is
a
huge
amount
of
there's
a
lot
of
interesting
academic
work.
There's
self
adjusting
computations
by
a
car
there's
the
adapt
on
work.
These
have
influence.
These
have
had
bigger
influence
in
the
functional
programming
space
like
the
Jane
Street.
C
Deeply
I
do
believe,
there's
a
good
interface
that
if
you
have
one
of
those
things
that
can
talk
to
a
server
to
get
a
partial
view,
then
that
should
be
able
to
talk
to
the
app
state
and
we've
done
some
thinking
around
I'm
surprised.
I
haven't
got
the
question
yet
it'll
I'm
sure
somebody
has
it
already
what
about
async
and
that's
another
sort
of
like
we're
still
figuring
that
out.
A
So,
regarding
the
partial
update,
stuff
kind
of
building
off
of
what
was
just
asked,
have
you
looked
into
instead
of
having
to
actually
you
know,
pass
these
references
around
and
whatnot,
rather
just
passing
IDs
around
inside
of
some
kind
of
an
any
component
system,
because
you
know
like
it's
a
little
more
amenable
for
even
the
async
thing,
like
you
just
mentioned,
wishes
will
also
point
part
of
my
questions
within
you
yeah,
but
I
was
just
wondering
if
you've
looked
into
that.
Yes,.
C
I
I
might
my
feeling
is
that
it's
less
of
a
good
fit,
but
that
also
probably
depends
on
what
you're
doing,
if
you're
doing
something
that's
more
game-like
in
simulating,
you
know
simulating
systems,
then
it's
likely
that
ECS
will
be
really
good
for
this
kind
of
tree
document,
tree
kind
of
modeling.
What
you're,
manipulating,
which
is
very
true
for
a
fun
editor.
Then
I
see
this
kind
of
tree
transformation,
kind
of
paradigm
as
being
a
more
natural
fit
and
more
composable
than
a
nice
es
style.
C
Don't
know
I
mean
certainly
the
there's
like
a
very
active
topic
of
discussion
on
the
dilip.
Now
of
how
do
we
get
futures
into
our
you
know
into
the
architecture
and
it's
complicated,
because
you
need
to
deal
with
the
run
loop
of
the
hosting
platform,
which
was
not
designed
to
be
an
executor
right,
and
so
that's
actually
one
of
the
first
questions.
C
Do
you
want
to
kind
of
make
it
into
an
executor,
or
do
you
want
to
have
it
so
that
it's
it's
separate
thing
and
just
interface
us
with
an
executor
running
in
a
different
thread?
I
actually,
don't
know
the
answer
that,
like
my
preference,
is
keep
it
separate
because
I
just
having
been
in
the
minds
of
dealing
with
platform,
run
loops
and
all
of
the
weird
kind
of
requirements
and
like
just
to
give
you
one
example:
you
don't
get
to
control
the
run
loop
when
a
file
dialog
is
open.
C
Then
it's
running
in
Windows,
specifically
it's
running
its
own
version
of
the
run
loop
so
like
you
would
not
have
to
deal
with
any
of
that.
If
you
just
had
an
executor
running
in
a
different
thread,
and
then
you
had
a
way
to
you
know
a
channel
or
some
you
know
some
kind
of
communication
so
that
your
stuff,
your
async
stuff,
that's
running
on
the
the
real
executor,
can
then
just
send
events
over
like
send
commands
or
some
you
know,
form
of
that.
C
That
would
be
a
cleaner
thing,
but
it
might
be
that
we
need
to
do
a
tighter
integration
so
that
you
can
express
you
know
kind
of
more
naturally,
acing
things
so
definitely
interesting
problem.
Definitely
we
have
people
like
I've
started
thinking
about
it.
We
have
other
people
that
are
like
kind
of
eager.
You
know
kind
of
really
really
kind
of
jumping
on
that.
So
watch
that
space.
G
C
Super
good
question
and
there
definitely
are
other
systems
that
kind
of
like
I,
think
Ice
D
is
probably
of
the
UI
frameworks.
It's
probably
the
one,
that's
closest
to
that
kind
of
Elm
style,
functional
approach
to
it
and
we
definitely
considered
it
and
I
think
it's
interesting,
but
when
I
was
kind
of
digging
into
it,
it's
like
one
of
the.
This
is
kind
of
a
digression
and
I,
don't
want
to
say
I,
don't
know
how
much
time
we
have,
but
I
was
looking
at
the
Martin
Clements
work.
What
is
it
called?
C
Auto
merge,
yes,
Auto,
merge
and
Auto.
Merge
has
a
thing
where
it's
generating
those
deltas,
but
in
order
to
be
orga
Nam
ik
in
generating
those
Delta's,
it
creates
a
proxy
object
and
then
you
mutate
that
proxy
object
and
then
it
created.
Then,
after
all,
your
mutations
are
done
to
kind
of
commit
those
mutations.
C
Then
you
get
a
delta
object
and
then
you
can
send
that
across
the
network
and
you
could
apply
that
same
thing,
so
that
was
actually
one
of
the
kind
of
design
sketches
that
I
was
doing
for
this
back
in
June
and
I
realized.
Why
do
two
steps
if
you're
gonna
have
a
proxy
object?
Why
not
do
the
mutation
in
place
and
then
the
dipping?
The
dipping
is
the
way
that
you
generate
the
Delta
from
the
proxy
object.
B
H
I
Have
to
admit
a
Google
draft
before
this
meetup
and
I
was
like.
Oh,
my
god
he's
a
really
big
deal.
This
is
really
exciting.
So
thank
you
for
sticking
around
for
me.
If
you,
google
him,
you
get
this
Wikipedia
page.
If
you
google,
me,
you
get
bad
tweets.
So
there's
that
so
hi
everybody
thanks
for
joining
us
tonight.
I'm
Gabby
and
I'm.
A
systems
engineer
at
CloudFlare
and
I'm
really
excited
to
talk
about
how
we
use
rust
to
write
delightful
developer
experiences
in
the
form
of
command-line
interfaces.
I
So
a
little
about
me
to
start
I
work
on
CloudFlare
workers,
which
is
our
functions
as
a
service
product.
So
imagine,
snappier,
lighter-weight,
Amazon,
lambda
functions
and
more
specifically,
I
helped
build
out
the
developer
experience
for
CloudFlare
workers.
So
this
means
that
I
wear
a
lot
of
hats
from
back-end
implementation
to
basically
building
tooling
to
help
our
work.
Customers
do
their
best
with
CloudFlare
workers,
so
you're
probably
wondering
how
rust
fits
into
the
situation,
and
that's
because
one
of
our
team's
primary
tools
is
written
and
rust.
I
So
your
first
question
might
be:
why
did
we
choose
rust
and
at
first
I
honestly,
was
fully
not
in
sync,
with
the
original
decision
to
use
rust
before
training
the
workers?
Team
I
was
a
golang
engineer
who
worked
on
back-end
services.
So
I
guess
you
could
call
me
a
gopher
and
Krabs
clothing
and
some
of
the
hesitations
I
initially
had
about
using
rust
for
a
CLI
was
the
trade-offs
between
learning
such
a
involved
systems.
I
Language
for
CL
eyes,
which
aren't
really
systems
there
were
moments
where
I
felt
like
Wrangler
features
that
would
have
been
is
so
much
that
would
have
been
like
pretty
fast
to
write
and
go,
took
a
lot
longer
to
develop
and
rust,
and
the
features
that
make
rust
rust
didn't
initially
seem
the
most
well
suited
for
CLI
work.
Yeah,
our
CLI
does
some
multi-threading.
So
if
roads
without
say
erases
are
extremely
useful,
but
did
we
really
need
the
minimal
runtime
and
guaranteed
memory?
I
Safety,
I
didn't
think
so
at
the
time,
but
I
knew
that
Ashley
had
choosen
chosen
rust
for
a
reason
and
I
really
wanted
to
get
on
the
same
page
and
as
I
continue
to
build
out
features
for
Wrangler.
Something
stood
out
to
me.
I
was
really
forced
to
think
about
all
of
the
possible
paths.
User
input
would
take,
and
when
I
wrote,
vaudrec
for
complex
patterns
of
user
input
and
configurations,
it
was
hard
to
leave
any
pattern
of
user
input
or
configuration
to
dangle.
I
This
is
because,
unlike
the
imperative
languages,
that
I
was
more
familiar
with
rust
exercises
pattern.
Matching
I
initially
actually
found
that
the
Wikipedia
definition
for
pattern
matching
useful,
so
I'll
quickly
go
through
that.
So
it
says
pattern
matching
is
used
in
some
programming
languages
as
a
general
tool
to
process
data
based
on
its
structure
and
in
these
languages.
These
languages
have
special
syntax
for
expressing
tree
patterns
and
a
language
construct
for
conditional
execution
and
Valley
retrieval
based
on
it.
I
So
pattern
matching
is
a
very
regimented
approach
to
evaluating
paths
of
execution
and
expected
and
unexpected
outputs
in
rusts
I'm
sure.
A
lot
of
you
already
know
this
pattern
matching
is
enforced
with
the
match.
Keyword.
The
match
keyword
is
extremely
useful
because
it
forces
you
to
account
for
every
possible
value
for
a
type.
This
forces
you
to
also
account
for
every
possible
type
of
input
that
a
user
can
provide
to
a
command
line.
Interface
pattern
may
treat
Pepa
or
pattern
matching
is
what
makes
rusts
increasingly
appealing
to
command
line
interface
developers.
I
So
you
need
to
be
prepared
for
odd
inputs
or
actions
who
users
may
provide
to
your
command
line
interface,
seriously
like
when
you
work
on
a
clivia
you'll
just
be
like.
Oh
everybody's
gonna
use
it
this
way,
and
then
maybe
this
so
you
have
to
be
prepared
and
it
happens
more
than
you
would
think
so.
Your
users
may
use
a
CI
feature
completely
different
than
what
do
you
expect.
I
It's
a
good
way
to
use
ice
cream,
in
my
opinion,
should
have
thought
that
Braille
and,
most
importantly,
you
want
to
make
sure
that
you,
yours
or
your
users,
don't
find
like
all
of
the
hidden
panics.
You
meant
to
remove
a
long
time
ago
that
have
your
swear
words
and
pattern
matching
really
helps
with
that.
I
So,
let's
dive
into
pattern
matching
features
a
bit
more.
This
one
already
has
been
touched
upon,
which
is
the
fact
that
pattern
matching
is
exhaustive
and
lets.
You
enumerate
all
the
ways
users
could
use
your
CLI,
but
beyond
that,
the
Reg
Menten
nature
of
pattern-matching
forces
developers
to
kind
of
self
document.
I
What
the
expected
behavior
for
a
Clio
CLI
is
when
I
built
features
on
top
of
other
Wrangler
contributor
work,
I'm,
able
to
see
the
intended
path
of
execution
and
understand
how
to
maintain
expected
behaviors,
as
a
user
of
our
CLI
would
see
it,
and
this
is
especially
useful
when
writing
things
like
complex
logic,
for
handling
config
file
inputs
in
behaviors,
like
some
configuration
values,
overriding
others
and
finally,
patching
matter
and
pattern.
Matching
with
keywords
like
match
is
just
a
lot
nicer.
Then
the
nests
of
heavily
nested
if-else
statements.
I
You
would
probably
get
in
a
more
imperative
language,
alright.
So
now
that
we've
gone
over,
why
I
think
that
rust
is
a
compelling
language
for
command-line
interfaces?
Let's
take
a
look
at
some
useful
crates
that
we
used
as
we
wrote,
Wrangler
the
first
one
is
one.
A
lot
of
you
probably
have
already
interacted
with
in
some
capacity.
I
I
Doing
this
without
clap
would
be
quite
involved,
and
it's
really
great
to
have
this
high-level,
abstract,
'add
approach
to
building
out
how
exactly
you
want
people
to
interact
with
your
CLI
reading.
These
arguments
from
our
clap
app
is
also
really
simple.
We
can
access
arguments
like
our
configuration
file,
name
with
the
value
of
function
and
we
can
just
get
along
with
our
program
after
that,
another
crate,
I
love
for
command-line
interfaces
is
config,
which
gives
folks
the
ability
to
easily
override
config
file
contents
with
arguments
passed
in
through
things
like
environment
variables.
I
This
is
especially
useful
if
your
CLI
is
going
to
be
used
in
CI,
because
it's
far
easier
to
pass
in
environment
variables
for
things
like
authentication
credentials,
then
having
to
manually,
create
a
configuration
file
with
that
information
in
CI.
So
this
is
how
we
make
Wrangler
available
on
platforms
like
github
actions.
I
So
let's
look
into
an
example
of
how
we
use
the
config
create
in
Wrangler,
so
you
can
see
that
we
first
create
a
config
object
and
then
we
begin
to
look
for
a
path
that
contains
our
configuration
file
and
if
that
path
does
exist,
what
we
do
is
we
take
all
of
the
key
value
pairs
from
this
tunnel
that
has
our
configurations
and
add
those
to
our
config.
Basically,
this
config
struck
this
base
like
a
wrapper
over
a
hash
map.
I
Then,
once
we've
looked
at
a
config
file
or
skipped
it
because
one
didn't
exist,
we
then
take
a
look
at
the
present
environment
variables
and
what
I
really
love
about
config
is
that
if
you
then
look
through
your
environment
variables
and
then
find
value,
some
environment
variables
that
can
flicked
with
those
and
your
config
file,
you
can
override
those
in
your
config
file
with
what
you
see
in
your
end
bars.
So
this
is
how
make
Wrangler
work
and
CI
it
becomes
really
straightforward
process.
I
I
I
Asians
I
was
gonna,
say,
rest
users,
and
then
the
Asians
came
out
a
little
late.
Your
your
users
might
not
be
row
stations,
they
might
not
not
have
things
like
cargo
installed
on
their
computers
and
they're,
not
gonna
want
to
have
to
install
that,
and
things
like
rest
up
in
order
to
be
able
to
get
your
CLI.
So
something
that
you
probably
will
want
to
support
if
you
write
a
CLI
and
rust,
is
the
ability
for
people
to
download
that
from
other
more
popular
managers
like
NPM.
I
So
the
good
news
is
that
it's
actually
not
that
hard
to
make
your
rust
CLI
available
on
NPM.
What
Wrangler
does
is
that
we
specify
an
NPM
directory,
and
this
directory
contains
everything
it
needs
to
be
pushed
to
the
NPM
registry.
So
it
has
a
package
Ehsan,
which
is
actually
what
defines
an
NPM
package,
and
we
can
just
take
this
directory
and
push
it
to
NPM.
I
The
most
important
thing
about
making
this
work
is
that
we
have
a
file
or
script
called
install
Wrangler
ejs,
and
what
that
does?
Is
it's
a
JavaScript
file?
That's
that
contains
logic
for
actually
pulling
Wrangler
from
the
github
binary
releases
API.
So
what
that
means
is
that
when
someone
installs
rangu
through
NPM
and
they
download
this
NPM
directory,
I
just
showed
you.
I
The
package
of
JSON
file
on
this
NPM
directory
has
a
post
installed
rule
that
NPM
will
run
after
downloading
this
directory,
because
the
script
is
one
that
downloads,
the
Wrangler
binary
from
github
for
you,
NPM
will
automatically
install
this
binary
for
you,
and
Wrangler
will
be
installed
on
this
machine
with
no
cargo
use
necessary.
So
this
is
a
great
way
to
make
sure
that
your
rust
written
CLI
is
still
accessible
for
potentially
a
majority
of
your
users
that
aren't
exactly
restorations.
Yet
you
know
that.
Thank
you
for
listening,
I'm
glad
this
is
a
little
short.
I
I
G
G
I
J
J
I
J
I
I
B
I
have
a
question
you
can
pass
if
this,
if
you
want,
but
so
I
asked
cabbie
to
add
the
bit
about
NPM,
because
when
I
started
using
Wrangler
I
found
it
was
it's
a
really
innovative
that
they
made
it
available
there.
Multiple
package
managers,
as
the
team
talked
about
any
of
the
Linux
package
managers.
So
you
can
app
get
not.
I
Yet,
honestly,
with
the
would
see
hi,
you
should
be
able
to
put
like
the
package
into
the
appropriate
distribution
endpoints,
but
we
haven't
done
that
yet
another
another
thing
we'd
actually
really
like
to
do
is
probably
docker
eyes
the
CLI,
just
because
there
are
cases
where,
like
people
are
just
more
used
to
running
this
type
of
software
completely
isolated
I
definitely
do
that
with
a
couple
of
CL
eyes,
so
it's
entirely
possible,
but
we
just
haven't
found
any
customer
needs
for
that.
Yet.
I
We
have
an
issue
literally
open
for
that
something
that
would
be
really
good.
Is
that
like,
if,
if
someone
is
running
an
old
version
of
Wrangler,
you
should
have
implemented
this
logic
far
long
ago,
but
if
they're
running
an
old
version
of
Wrangler,
they
do
a
check
to
the
github
releases
API
and
they
say
like.
Oh,
are
you
on
the
newest
version
or
not?
That
would
be
really
useful,
but
what's
remarkable
is
that
at
least
our
users
have
been
very
active
about
updating
their
versions.
You
definitely
can't
take
that
for
granted,
though.
H
L
I
I
I
H
I
Too
pain
in
the
butt
honestly
I
think
that
writing
tests
for
CLI
is
like,
arguably,
the
hardest
part
of
it.
Just
because
there
are
so
many
paths
you
really
need
to
cover
coverage
is
really
hard
to
attain.
What
we
do
for
integration
tests
is
not
the
most
elegant.
We
often
do
actually
like
run
the
Wrangler
command
in
these
tests
to
test
what
actual
input
would
look
like
from
a
user
perspective
and
verify
that
the
output
is
what
we'd
expect
I
feel
like.
I
There
must
be
more
frameworks
for
integration
testing
of
CL
eyes,
but
we
just
haven't
had
like
the
resources
to
really
really
do
our
integration
tests
at
the
moment,
but
that's
definitely
a
place
where
I'd
love
to
see
more
innovation.
Just
because,
like
there's
tons
of
libraries
for
mocking,
you
have
like
docker
composer
traditional
integration
tests
between
services,
but
when
they
come
to
CL
is
integration.
Tests
are
a
little
bit
more
of
a
an
open
question
with
a
lot
more
options,
none
of
which
are
the
best.
M
Hi
great
talk,
I've
worked
with
clap
and
I.
Think
there's
another
crate
called
args,
where
it
kind
of
puts
together
clapped
as
procedural
macros.
You
just
annotate
a
struct
with
and
it's
yeah
it's
awesome
stuff.
But
one
pattern
I
find
myself
using
a
lot
is
basically
extracting
configuration
arguments
into
some
global
like
struck.
That's
put
together
using
lazy,
static
or
other
approaches
to
global
variables,
and
it
doesn't
feel
very
clean
to
use
global
variables
like
that.
So
I'm
just
wondering
if
you
have
any
suggestions
for
how
to
clean
that
sort
of
thing
up,
yeah.
I
Like
honestly,
we
don't
use,
we
don't
store
any
use
in
for
me,
the
global
variables
at
any
point,
what
we
focus
on
is
like
basically
filling
out
a
necessary
struck
that
contains
things
like
configuration
arguments
and
we
just
pass
it
through,
like
literally
all
the
functions
that
are
cascaded
from
the
main
function.
That,
like
reads
all
the
arguments
from
from
clap.
That's
worked
out
for
us
and
like
yeah,
it's
way
more
passing
around,
but
I
think
it's
kind
of
nice
to
be
able
to
actually
like
chain
all
those
calls
as
well.
I
Solutions,
what
do
you
mean
by
analytics
in
this
case?
No,
no,
like.
K
I
Really
interesting,
we
haven't
even
like
discussed
that
yet
for
Wrangler,
but
it
would
be
like
a
really
cool
way
to
understand
how
people
are
using
Wrangler
and
you
know
where
we
could
best
improve
their
experience.
Like
that's
a
really
good
idea
and
I
honestly,
we
haven't
even
touched
that
yet,
but
it's
something
for
us
to
really
think
about
github.