►
From YouTube: How AWS is building the Rust SDK and how you can use it today - Zelda Hessler - Rust Linz June 2022
Description
Last year, AWS launched a new SDK for Rust in developer preview (https://aws.amazon.com/about-aws/whats-new/2021/12/aws-sdk-rust-developer-preview/), enabling customers developing in Rust to use the language constructs they are used to, and to provide customers new to Rust an SDK that behaves similarly to SDKs they have used in other language environments. Zelda, a member of the AWS Rust SDK team, will be giving a whirlwind tour of the AWS Rust SDK. In this talk, she’ll cover:
- How to use the SDK to make requests
- What’s actually happening when using the SDK to make requests
- How the AWS Rust SDK team generates SDKs for 300+ Services
- What to do if you’re interested in contributing to the SDK
A
All
right,
yes,
it
is
my
pleasure
to
be
here,
I'm
very
excited
to
present
on
this.
I
joined
the
aws
rest
sdk
team
several
months
ago,
almost
half
a
year
now
and
I've
been
helping
them
build
it,
and
I've
also
been
presenting
on
it
a
little
bit.
I
presented
it
re
invent
last
december
for
anyone.
That's
not
familiar.
Aws
stands
for
amazon
web
services.
A
So
what
am
I
going
to
cover
tonight?
We're
going
to
look
a
little
bit
at
how
to
use
the
sdk
to
send
a
request
to
s3,
which
is
our
simple
storage
service,
we're
going
to
look
at
what
actually
happens
with
that
request
as
it's
getting
sent
we're
going
to
talk
about
how
we
actually
co-generate
all
these
sdks
for
300
plus
services.
A
It
was
316
different
sdks
that
we
produced
the
last
time
counted
and
we're
also
going
to
talk
a
little
bit
about
what
you
can
do
if
you're
interested
in
contributing
to
the
sdk,
because
it's
all
open
source
and
then,
of
course,
at
the
end,
we're
going
to
have
time
for
questions
and
answers
so
to
start
making
a
request
to
s3.
A
Now,
there's
a
lot
of
extra
context
for
people
here.
I've
shared
these
slides
in
this
meetups
discord
channel
so
that
people
can
click
on
all
these
links,
because
every
few
slides
there's
going
to
be
four
or
five
links
for
you
to
take
a
look
at
I've
linked
here
are
two
repos
one
for
the
sdk
and
one
for
the
code
generation.
Repo
I've
also
linked
our
repo
that
contains
all
of
our
official
examples.
A
A
So
there
are
a
couple
things
I'm
not
going
to
be
covering
in
this
talk
and
that's
going
to
be
stuff
like
creating
an
aws
account
how
to
get
and
store
your
access
keys,
how
to
create
a
new
rust
app
with
cargo,
or
I'm
not
I'm
not
going
to
talk
about
how
to
do
async
runtime
stuff
with
tokyo,
specifically
we're
going
to
be
using
it,
but
I'm
going
to
kind
of
gloss
over
a
lot
of
the
basic
things.
However,
again
I
have
included
links
to
all
those
things.
A
A
Async,
we
use
tokyo
a
lot,
although
technically
the
sdk
can
be
runtime
agnostic,
which
I'll
talk
a
little
bit
about
later,
but
in
this
example
that
we're
looking
at,
we
are
defining
our
main
function.
We're
saying
that
it's
valuable
that
it
might
return
an
error,
we're
initializing
logging,
which
is
always
a
really
good
thing
to
do.
We
have
a
lot
of
logging
setup
in
the
sdk
to
help
you
understand
what's
actually
happening
and
the
first
real
thing
that
we're
doing
here
is
on
line
5
we're
creating
a
config,
an
sdk
config.
A
Every
client
kind
of
has
its
own
needs,
but
there
are
a
lot
of
shared
things
that
they
need
to
know
about,
and
all
that
is
encompassed
in
this
struct
and
all
we
have
to
do
to
create
one
is
call
aws,
config,
colon
colon
load
from
end
and
then
await
that
and
that's
it.
This
will
read
your
environment,
your
file
system,
it
might
even
make
calls
to
like
fetch
credentials
from
remote
sources,
and
it
does
this
by
looking
at
things
that
are
the
same
for
every
single
aws
sdk.
A
So
if
you've
already
set
up
your
computer
to
work
with
another
sdk
for
aws
like
the
python
sdk
or
something
like
that,
then
this
is
kind
of
like
a
drop
in
replacement.
You
can
just
run
this
and
it's
going
to
load
all
that
configuration
from
your
environment.
A
So
next
we're
going
to
create
our
client,
specifically
we're
going
to
create
a
client
to
talk
to
our
simple
storage
service.
Now
I
may
have
mentioned
earlier:
simple
storage
service
is
for
storing
objects,
basically
just
any
data,
and
it
organizes
that
data
into
buckets,
and
you
refer
to
that
data
with
keys.
A
So
here
we're
creating
our
s3
client
and
all
we
have
to
do
to
do.
That
is
to
pass
it
that
shared
config
and
then
that's
it.
We
now
have
a
client
next
we're
going
to
use
that
client
to
create
a
builder
function
for
our
request.
All
requests
in
the
sdk
get
constructed
by
these
builders.
Where
you
say
what
builder
you
want,
you
call
methods
to
set
any
inputs
that
it
might
require.
A
You'll
see
that
we
have
that
little
question
mark
try
operator
at
the
end
which,
if
an
error
occurs,
it'll
bubble
it
up
and
then
get
emitted,
and
that's
it
like
you
can
you
can
create
your
config,
create
a
client,
make
a
call
in
just
three
lines
like
that
for
most
users,
it's
going
to
be
this
simple
and
we're
really
proud
of
how
easy
we
made
that,
of
course,
it's
not
really
that
simple
right,
like
a
lot,
is
actually
going
on.
So
what's
really
happening
under
the
hood.
A
A
So
we
can
get
our
config
back,
so
you
can
manually
create
these
config
loader
structs,
but
really
you
shouldn't
need
to
it's
best
if
you
use
load
from
amp
and
just
rely
on
storing
all
your
config
in
your
environment
as
opposed
to
setting
things
manually
in
your
program.
However,
if
you
do
need
to
do
that
for
testing
or
because
you
think
it's
going
to
provide
a
better
experience
for
users
of
your
app,
then
that
is
okay,
so
the
config
loader
sets
all
these
different
things.
A
A
You
also
have
to
provide
a
region
because
aws
is
regionalized
when
you
set
up
something
like
s3,
you
put
things
in
specific
global
regions
and
that's
basically
an
abstraction
over
the
location
of
these
things.
Stuff
that's
closer
together
will
run
faster
than
things
that
are
farther
apart,
because
that's
the
internet.
A
You
can
also
set
retry
and
timeout
related
stuff
here,
and
that's
just
you
know,
basic
things
for
making
http
requests
an
interesting
one
in
between
those
two
is
sleep,
and
so
earlier
I
mentioned
that
we're
kind
of
agnostic
over
async
runtimes.
So
this
is
how
we
can
achieve
that
at
the
very
lowest
level.
A
What
we
really
need
from
an
async
runtime
is
the
ability
to
thread
sleep,
the
ability
to
say
wait
for
this
amount
of
time
and
then
tell
us
when
that
time
is
elapsed.
We
need
that
for
retries.
You
know
if
a
sdk
is
getting
throttled
because
you're
sending
a
lot
of
requests,
we
have
to
be
able
to
wait.
We
have
to
be
able
to
see
when
a
timeout
has
elapsed
and
so
by
allowing
people
to
supply
their
own
thread.
A
We
also
have
a
provider
config,
that
is
our
abstraction
over
things
like
your
environment
variables,
your
file
system,
things
like
that,
and
that's
really
helpful
during
testing,
because
in
testing
you
know
you
want
to
be
able
to
run
tests
in
parallel.
Probably
you
don't
want
them
to
all
be
setting
stuff
in
the
actual
environment
and
overriding
things
you
want
to
be
able
to
set
a
specific
consistent.
A
You
know
environment
for
each
test,
and
so
we
do
that
with
the
provider
config
and
then.
Lastly,
we
also
want
the
sdk
to
be
generic
across
http
frameworks.
Right
now,
it's
pretty
heavily
based
on
hyper,
but
we're
slowly
adding
the
ability
to
switch
out
different
parts
to
use
whatever
http
framework
you
think
is
best
for
your
needs.
A
Okay,
so
that's
a
lot
of
information
like
where
does
that
even
come
from
well,
it
gets
set
mainly
in
two
ways,
these
kind
of
very
simple
config
structs,
where
it's
just
saying
like
hey
for
this
just
insert
this
small
piece
of
config
into
the
larger
shared
config.
It's
just
structs
filled
with
data
determining
default
values.
In
this
case,
it's
really
simple,
because
they're
either
just
hard
coded
things
or
they're
just
left
unset,
but
for
really
complex
things.
You
know
like
credentials
and
so
on.
We
use
these
things.
A
That
optionally
returns
one
of
those
config
structs
we
box
or
arc
them,
so
we
can
pass
them
around,
not
worry
about
ownership,
so
one
of
the
cool
things
about
providers
is
that
we're
able
to
chain
multiple
providers
together,
and
so
one
example
of
doing
that
is
like
say
we
want
to
get
your
timeout
config.
You
could
define
that
with
environment
variables.
A
These
are
great
for
when
determining
default,
values
is
very
complex.
You
know,
because
we
have
to
look
in
multiple
places
or
because
we
might
have
to
make
async
calls.
You
know
we
might
have
to
call
some
sort
of
service
that
will
provide
the
credentials
on
the
spot
and
that's
basically
how
all
that
stuff
works.
A
So
I
said
earlier
that
you,
you
generally
don't
need
to
override
these
things
and
it's
best
to
set
them
in
your
environment.
However,
we
do
of
course
provide
the
ability
to
do
so
so
in
this
example
we're
doing
from
end
instead
of
load
from
n,
and
that
allows
us
to
modify
this
config
loader
before
we
actually
use
it
to
get
all
that
config
from
all
those
different
places,
and
in
this
specific
example,
we're
saying,
use
the
default
region
provider
and
it's
a
chain.
A
One
thing
to
be
careful
of
and
a
mistake
that
we
see
sometimes,
is
that
when
you're
overriding
these
things,
you
have
to
make
sure
that,
if
your,
if
your
provider
that
you're
inserting
here
might
not
provide
something,
then
you
should
probably
combine
that
with
the
default
provider
right,
because
if
you
get
rid
of
the
default
provider,
then
there's
a
chance
that
you're
not
going
to
set
anything
here,
in
which
case
the
sdk
is
going
to
panic,
so
that
we
can
bring
your
attention
to
this.
A
A
Most
of
them
are
exactly
the
same
as
the
sdk
config.
However,
a
couple
services
do
have
these
service
specific
options
that
they
need
and
by
creating
service
specific
configs
even
for
services
that
don't
need
them.
It
allows
us
to
preserve
backwards
compatibility
if
they
need
to
add
those
service.
Specific
things
at
a
later
point,
one
example
of
a
specific
thing
is
that
our
elastic
cloud,
compute
service
ec2,
requires
an
item
potency
token
to
be
sent
with
a
lot
of
different
requests.
A
So
when
creating
a
service
client,
the
client
new
method
takes
that
reference
to
an
sdk
config.
It's
calling
that
from
impul
under
the
hood
to
convert
it
to
a
service
config
and
then
storing
that
within
itself
and
for
testing
purposes,
it's
totally
possible
to
create
a
client
directly
from
a
service
config
and
an
http
connection,
and
we're
going
to
kind
of
look
at
that.
A
little
bit
later.
A
And
there
are
two
main
things
to
focus
on:
there's
a
lot
of
text
in
this
area,
but
what's
really
happening
is
that
we're
setting
up
some
kind
of
middleware
we're
setting
up
some
kind
of
smithy
client?
A
What
is
middleware
and
what
is
a
smithy
client
we'll
talk
about
that
in
a
second,
but
what
this
code
is
doing?
Is
it's
taking
a
service
config
that
we
got
because
it
automatically
got
converted
from
us
or
for
us
we're
looking
at
the
retries,
the
timeouts,
the
sleep
implementation,
things
like
that
we're
setting
up
this
thing
called
the
default
middleware
and
we're
putting
that
all
together
in
this
builder
that
eventually
produces
a
service
client
for
us
and
that
service
client.
You
can
see
it
has
that
arc
and
there's
a
handle
inside
it.
A
A
Middleware
is
basically
a
way
of
defining
reusable
behavior
for
either
your
client
or
your
server,
and
sometimes
it's
general
purpose
behavior.
Sometimes
it's
more
application
specific,
so
a
general
purpose
thing
might
be
like
logging
or
something
like
that,
and
a
more
specific
thing
might
be
some
form
of
request
signing.
So
you
would
set
up
a
bunch
of
middlewares
one
on
top
of
the
other,
and
then
it's
like
a
pipeline
that
you
can
send
a
request
through
or
that
you
can
send
a
response
through
and
it
will
inspect
it
and
modify
it
as
needed.
A
So
at
the
end
you
have
a
request:
that's
ready
to
be
sent
off
to
some
service
or
you
have
a
response.
That's
been
processed
in
whatever
way
your
app
requires,
and
then
smithy
is
the
name
of
the
language
that
all
of
the
aws
services
are
modeled
with
smithy
rs
is
our
specific
cogen
tool
or
another
collection
of
a
bunch
of
tools,
but
smithy
itself
is
kind
of
the
whole
thing.
It's
the
modeling
language
itself.
A
A
So
all
services
right
now
use
the
same
middleware
stack.
We
have
a
basically
like
a
couple
of
default
things
that
we're
always
going
to
need
when
we're
making
requests
to
amazon
stuff.
So
that
includes
like
that
endpoint
resolution,
which
we
talked
a
little
bit
about
the
config
thing
like
config,
will
set
all
the
logic
brow
that
happens,
and
then
this
will
set
up
the
thing
that
will
actually
figure
out
where
stuff
is
going
at
the
time
we
send
the
request.
A
It'll
allow
us
to
insert
user
agent
headers
into
requests.
It
will
allow
us
to
sign
requests
and
basically
set
these
authorization
headers,
which
are
sorted
like
credentials
technically
they're,
not
because
sending
your
actual
credentials
and
a
request
would
be
unsafe.
A
A
So
I
mentioned
a
smithy
client
a
little
while
back.
I've
also
talked
about
service
clients.
Those
are
different
things
and
it
can
be
kind
of
easy
to
get
them
confused
when
you're
very
new
to
the
sdk.
I
know
it
was
a
little
hard
for
me
at
first
service.
Clients
are
actually
a
wrapper
around
that
services,
config
that
it
needs
and
then
like
a
pool
of
actual
http
clients,
smithy
clients,
as
we
call
them
in
this
and
a
smithy
client,
is
a
tower
service
composed
of
a
bunch
of
different
layers.
A
Again,
just
like
the
middleware.
It's
actually
almost
the
same
thing.
It
kind
of
looks
like
the
same
thing,
except
it
has
a
couple
of
extra
things
like
timeouts
retries.
How
requests
get
dispatched
dc
realization
things
like
that?
We're
going
to
look
at
that
in
a
little
bit.
A
So
under
the
hood
dispatching
an
operation,
so
this
is
like
earlier
when
we
had
that
list
buckets
thing
and
then
we
did
send
under
the
hood.
We're
dispatching
an
operation,
so
requests
made
to
a
service
are
represented
as
operations
in
the
model
like
this
actual
smithy
model.
The
word
operation
is
a
shape,
a
kind
of
thing
that
associates
inputs
and
outputs
and
requests
specific
errors,
and
in
the
sdks
we
have
a
type
called
operation
and
that
gets
created
from
an
input
sent
by
a
client
and
then
either
the
output
structure
and
error.
A
Struct
is
returned
in
a
result
and
the
function
that
we
use
to
turn
that
input
into
an
operation
is
unsurprisingly
make
operation,
and
it
does
that
actual
conversion.
It
makes
the
operation
which
inside
it
contains
an
actual
http
request,
which
is
like
a
specific
rust
library,
the
http
library
that
pretty
much
all
web
frameworks
and
rest
are
based
on
yeah,
so
operation
construction.
A
When
we're
creating
that
service
client.
That's
like
setting
up
the
config
setting
up
the
middlewares
like
we
talked
about
the
next
thing
that
we
do
is
we
call
the
an
appropriate
method
to
create
a
builder.
So
in
our
first
example
that
was
list
buckets
and
that
starts
building
a
list,
buckets
input
which
is
going
to
be
used
to
create
that
list
buckets
operation
and
importantly,
that
builder
inside
it
has
a
handle
to
the
smithy
client.
So
our
service
client
created
this
thing.
A
That
has
all
the
information
needed
to
send
a
request
and
it
copied
or
gave
a
reference
to
its
internal
http
client,
so
that
request
can
just
be
sent
at
its
own
leisure
us,
or
rather
at
your
leisure.
A
So
next
we
set
all
the
required
configuration
for
that
builder
and
then
call
send
so
in
the
list
buckets
example.
We
didn't
actually
have
to
set
any
different
things,
but
we're
going
to
see
an
example
in
a
minute
where
we
do
set
a
couple
of
different
fields,
and
it
all
happens
through
calling
methods
on
builder
next
after
send
is
called
the
send
method
is
responsible
for
building
the
input
struct
from
all
those
different
things
that
we
just
set,
and
it
converts
that
into
an
operation
with
make
operation,
and
that's
where
you'll
get
an
error.
A
If
we
can't
construct
an
http
request,
which
is
I
struggle
to
think
of
a
situation
where
this
would
actually
happen,
it'll
pretty
much
never
fail,
but
if
there
was
something
wrong
with
it,
if
something
caused
the
request
that
was
created
to
be
invalid,
this
is
where
you'd
see
an
error,
and
it
would
tell
you
what
you
should
do
about
that.
A
A
A
A
Okay,
we
can
do
a
lot
of
this
stuff
manually
when
we
did
it
the
nice
way.
It
was
three
lines
right
and
it
just
worked
kind
of
magically,
but
for
testing
we
often
do
it
the
more
difficult
specific
way,
because
it
lets
us
override
a
lot
more.
So
in
this
case
we're
building
a
service
sdk
directly
by
getting
the
config
builder,
setting
a
credentials
provider
with,
like
hard-coded
testing
credentials,
setting
the
region
to
always
be
usc
1.
we're
creating
our
own
http
connection
and
injecting
that
into
a
service
clients
new
thing
to
create.
A
A
Then
we
create
our
operation
manually.
So
we
have
our
input
here,
but
we're
saying
this
is
for
put
object
by
the
way,
not
list
bucket,
so
we're
calling
builder
methods
on
it.
We're
saying
I
want
to
put
an
object
to
my
test
bucket.
I
want
to
name
it
key.txt
I
want
to
it.
Has
this
body
of
some
test
text,
so
that's
what
we're
going
to
upload
is
the
actual
object.
A
Then
we
call
build
that
takes
that
builder,
that
we
just
constructed
turns
it
into
an
input
and
that
could
fail.
But
since
this
is
a
test
we
know
it's
not
going
to
fail,
we
just
unwrap,
then
we
call
make
operation
on
that
resulting
input
and
we
have
to
pass
the
service
config
into
it.
Just
like
we
saw
it
was
happening
for
us
when
we
called
send.
A
Originally,
we
have
to
await
that
just
like
we
talked
about
before
and
then
next
we
do
a
cool
thing
that
we
we
do
in
testing,
where
we
can
actually
take
that
operation
before
sending
it
and
insert
certain
hard-coded
things.
So,
like
we
hard
code,
the
date
that
the
operation
is
getting
sent
because
we're
going
to
check
the
request
at
the
end
of
this
test-
and
we
don't
want
that
check
to
fail
because
the
request
was
sent
later
than
the
first
time.
We
did
it
right.
A
Then
we
call
the
call
method
ourselves,
so
everything
that
I've
just
covered.
All
of
that
happens
automatically
when
you
call
send,
but
as
you've
seen
here.
If
you
have
specific
needs
normally
testing,
you
can
kind
of
do
the
harder,
more
verbose
version
and
switch
out
any
part
of
it
that
you
need
for
whatever
purpose
you
have.
A
So
when
call
happens,
a
lot
of
interesting
stuff
is
happening
in
there
too.
We
actually
create
a
new
tower
service
whenever
you
call
call
and
it's
basically
its
own
server.
That
has
one
job
just
to
send
your
request
and
that's
it
nothing
else.
A
It
will
modify
that
request
by
passing
it
through
a
bunch
of
different
layers
and
then
it
will
actually
dispatch
it,
send
it
over
the
wire
and
then
when
it
gets
the
response,
it's
going
to
deserialize
that
either
into
the
successful
struct
or
some
error
right
and
return
a
result
to
us
now,
errors
can
happen
for
all
sorts
of
reasons.
A
Things
like
a
connection
issue,
or
maybe
there's
dns
issues
or
socket,
hang
up
things
like
that
or
it
could
be
the
service
responding
with
an
error
like
hey
you're,
sending
me
too
many
requests,
or
you
forgot
to
set
this
required
field
in
your
request,
or
you
know
the
thing
you
were
looking
for
told
me
to
look
for,
doesn't
exist
stuff
like
that.
A
And
so
inside
that
call
method.
This
is
what
it
looks
like
when
it's
constructing
that
service.
It
creates
a
new
service
builder.
It
adds
timeout
layer.
It
has
this
layer
for
retries.
It
has
another
timeout
layer
because
we
actually
add
one
layer
per
kind
of
timeout.
We
support.
We
support
multiple
kinds.
A
A
It
creates
this
dispatch
layer
which
will
take
our
operations
request
and
actually
dispatch
that
request
over
the
wire
and
then
lastly,
we
define
that
connector,
which,
if
you're
doing
this
automatically
like,
if
you're
doing
the
nice
three
line,
config
client
send
version
that
connector
is
going
to
be
determined
for
you.
It's
going
to
be
based
off
of
is
russell
russell's,
russ
tls
or
like
a
native
some
sort
of
https
connector
under
the
hood,
and
we
basically
picked
that
for
you,
although
you
could
replace
it.
A
If
you
wanted,
and
then
in
that
testing
example
that
we
saw,
this
will
be
that
test
connector.
We
actually
have
a
bunch
of
really
cool
test
connectors
for
this,
like
we
have
one
that
will
inspect
every
request
you
send
with
it
to
make
sure
that
it
looks
the
way
you
expect,
and
that
will
respond
with
these
canned
responses,
so
that
you
can
make
sure
that
your
app
always
handles
the
responses
in
the
way
that
you
want.
A
Another
cool
thing,
though,
is
that
like
when
we
create
this
stuff,
because
it's
creating
a
new
service
stack,
we
don't
have
any
confusion
about
like
if
we
change
the
configuration
is
that
gonna
change
what's
gonna
happen
with
my
service
before
I
send
it
like.
You.
Don't
worry
about
stuff
like
that,
because
this
has
all
of
that
state
contained
within
it,
and
it's
perfectly
ready
to
make
that
request
at
any
time,
and
you
can
make
a
bunch
of
these
services
just
on
the
fly
which
really
surprised
me
when
I
first
started
out.
A
I
thought
it
was
like
kind
of
weird,
but
it's
actually
really
cool
and
that's
it
after
only.
I
don't
know
like
a
thousand
steps
right.
We've
actually
sent
a
request,
and
it's
it's
great
that,
like
all
that
can
be
so
easily
expressed
in
just
those
three
lines,
so
that
was
a
lot
of
rest
code.
We
looked
at
right
like
where
does
all
that
come
from?
It's
got
come
from
somewhere.
I
said
that
there
were
316
services.
I'll
tell
you,
we
don't
write
it
all
by
hand.
We
have
to
co-generate
it
right.
A
It's
kotlin,
we
use
a
bunch
of
kotlin.
Actually
we
had
considered
using
rust
for
this,
but
all
the
canonical
tooling
for
smithy,
which
is
a
pre-existing
thing
that
all
the
other
aws
sdks
are
based
on.
All
that
tooling
is
written
in
java,
and
so
in
order
for
us
to
like
just
get
started
right
away,
writing
this
sdk
and
getting
it
out
to
people
that
need
it.
A
We
decided
that
it
was
a
better
idea
to
take
all
these
great
things
that
already
existed
and
build
on
top
of
them,
rather
than
try
and
replace
them,
which
is
a
you
know,
a
lot
of
rest
developers.
We
always
want
to
rewrite
things
and
rest
and
there's
definitely
a
bit
of
a
desire
to
do
that
sometimes.
But
we
have
really
benefited
a
lot
from
being
able
to
use
all
these
existing
things
and
it
frees
us
from
having
to
update
and
maintain
all
those
tools
which
is
the
real
secret.
A
So
like
how
does
code
join
work?
Well,
we
talked
a
little
teeny
bit
about
smithy
earlier
and
how
we
use
that
to
define
our
models.
Our
codegen
will
look
at
those
models
and
turn
them
into
a
rest,
so
it
will
look
at
smithy.
Primitives
smithy
has
its
own
way
of
defining
integers
and
strings,
and
things
like
that
and
turn
those
into
rust
primitives.
A
Like
later,
we
define
these
writers,
which
are
basically
super
powered
string,
formatters
to
create
files
and
insert
this
rust
code
into
them.
We
also
have
things
that
will
create
rust
crates
for
us
and
manage
the
dependencies
of
those
crates.
We
have
all
these
things
that
will
set
up
serialization
and
deserialization
for
all
these
models,
so
that
we
can
send
requests
and
interpret
the
responses
that
come
back.
A
It
also
controls
how
these
service
clients
get
created
with
all
their
different
operation
builders
and
how
their
config
works,
and
it
also
sets
up
the
cogent
for
those
specific
operations
like
how
they
actually
work
inside.
A
And
then
also,
we
have
kind
of
the
flip
side
of
this,
or
rather
another
layer
on
top
of
it,
which
is
aws
specific
stuff.
So
smithy
is
actually
this
generic
framework
that
anyone
can
use
to
define
any
kind
of
service,
not
just
one
that
you
would.
You
know
see
at
aws,
but
there
are
other
companies
that
actually
use
smithy
to
define
their
own
services
and
generate
sdks
for
those
services
for
aws
services.
That
means
we
need
to
add
a
couple
of
special
aws,
specific
things
to
our
code
gen.
A
As
I
talked
about
earlier,
adding
user
agents
to
requests,
adding
aws,
specific
fields
to
like
service
client
configs,
adding
license
headers
for
amazon
to
all
of
our
generated
files,
generating
our
readmes
for
each
crate
and
then
inlining,
something
called
inlineables,
which
is
not
too
descriptive,
but
I'll
explain
what
that
is
in
a
moment
as
well.
A
So
I've
been
talking
about
models,
we
haven't
actually
looked
at
one.
This
is
what
they
look
like.
You
can
see
that
this
is
the
model
for
that
list,
bucket
request
that
we
sent
at
the
very
beginning
of
this
talk
and
it
defines
an
output
which
targets
some
sort
of
shape,
in
this
case
the
output
shape.
A
We
actually
read
that
documentation
and
output,
that
in
the
crate,
so
that
when
you
go
to
docs
rs,
you
will
see
that
documentation,
and
it
also
says
that
this
is
an
http
operation
where
we're
supposed
to
get
from
a
specific
uri
and
that
a
success
response
is
going
to
be
a
200.,
and
so
just
looking
at.
That
is
enough
information
for
us
to
generate
this
call
to
list
buckets
you'll
notice
here
that
it
doesn't
have
an
input
struct,
that's
because
list
buckets
doesn't
take
any
input.
A
It
just
shows
you
all
of
your
s3
buckets
now.
The
thing
about
that
is
that
in
rust,
when
you
have
a
function,
signature
with
like
inputs
and
outputs,
you
cannot
change
that
signature
without
it
being
a
breaking
change
right
like
if
we
added
a
new
parameter
to
a
function,
and
then
you
update
it
to
that
version
that
would
break
your
code
and
stop
it
from
compiling.
A
We
don't
want
that
to
happen.
We
really
don't
like
breaking
people,
we
don't
ever
want
to
have
to
do
it,
and
so
in
situations
like
this,
it's
possible
that
they
might
add
an
input
in
the
model
in
the
future
that
the
s3
team
might
modify
that
model
in
that
way
because
for
them
that's
not
considered
a
breaking
change,
but
unless
it
is,
and
so
what
we
have
to
do
is
we
will
generate
a
synthetic
symbol.
A
We'll
pretend
that
this
has
an
input
that
just
has
nothing
in
it
just
so
that
we
can
make
sure
that
when
we
make
these
function
signatures
that
they
will
never
change,
even
if
they
add
stuff
in
the
future
and
there's
a
couple
of
more
links
in
here,
I
link
to
where
all
of
our
smithy
models
are.
I
link
to
the
traits
that
you
can
use
to
customize
like
a
specific
model
and
better
explain
what
it
does.
A
Smithy
models
are
defined
in
either
the
smithy
language
or
json.
In
our
case,
we
consume
json
files.
A
A
So
that
stuff
that
I
talked
about
just
reading
the
model-
that's
not
exactly
quite
enough
to
make
a
working
sdk.
So
we
have
all
this
other
stuff
too.
We
have
shared
types
across.
You
know
all
smithy
services
that
they
would
need
usually
related
to
http
stuff
other
core
http
things
like
what
an
http
body
is
utilities
for
setting
modifying
headers
things
like
that.
We
have
our
byte
stream
struct,
which
is
our
abstraction
over
any
streaming
collection
of
bytes,
so
you'll
be
using
that
anytime.
A
You
send
a
request
with
a
body
or
receive
a
request
of
the
body.
We
have
that
service
client
based
on
tower
that
we
talked
about
earlier.
A
We
have
other
utilities
and
abstractions
that
are
kind
of
they're,
not
just
sdk,
specific
and
they're,
maybe
not
even
runtime
crate,
specific
they're
just
used
across
all
of
our
runtime
crates,
and
we
also
have
the
actual
code
for
serialization
and
dc
realization.
It's
very
generic
and
that
gets
put
together
when
we're
generating
sdks,
and
we
also
have
our
aws
specific
ones
again,
just
like
with
codegen.
A
And
I
glossed
over
this
earlier,
we
also
have
inlineables.
So
the
general
thing
is
that
we
want
to
avoid
writing
rust
within
kotlin
as
much
as
possible,
because
it's
just
it's
not
very
easy
right
to
do
all
your
coding
in
a
string.
We
want
nice
like
ide
support,
and
we
also
want
it
to
be
easily
testable,
with
existing
tools
like
cargo
and
so
on.
So
what
we
do
for
that
is.
A
So
that
was
a
lot
of
stuff,
but
that
is
about
as
deep
as
it
goes,
and
the
the
core
thing
to
remember
is
that
it's
all
layers,
we
have
multiple
kinds
of
configuration
that
all
get
collected
and
passed
through.
A
So
if
that
sounds
interesting
and
exciting
to
you,
I
would
love
to
see
contributions
from
all
of
you
to
the
sdk.
It's
all
fully
open
source.
We
love
getting
feature
requests
from
people.
We
actually
prioritize
our
feature
requests
based
on
the
number
of
thumbs
up
they
received
on
github,
because
it's
very
important
to
our
team
to
make
sure
that,
like
we're,
building
things
that
people
that
want
to
use
aws
need
right
now
we
love
prs.
A
A
We
write
these
all
the
time
on
the
team
for
large
or
complex
changes
where
we
want
to
make
sure
that
they
get
really
good
review,
because
it's
not
enough
for
us
to
build
something
that
works.
We
want
to
build
the
best
solution
that
we
can
think
of
that
works.
You
know
one.
That's
really
easy
and
simple
to
use
and
understand
anyone
can
submit
an
rfc
and
we
have
a
template
to
help.
You
get
started
writing
one,
but
if
you're,
you
know
afraid
to
maybe
start
writing
one
right
away.
That's
totally!
Okay!