taro

taro

Best practice between `String.t()` and `binary()`?

I’ve learnt that phx.gen.auth uses Base.url_encode64() to convert binary() to String.t(). If I just pass a binary, consumer would malfunction without exception.

And It seems it’s hard to draw a clear line between them. There is no built-in guard for String.t(). Is Elixir completely incapable of telling them apart? And, is Base.url_encode64 the best practice when converting one? What other options I have?

Marked As Solved

brettbeatty

brettbeatty

The problem with that is you have to look at every piece of the binary to check that it’s a valid string, which you can’t really do in a guard. If you need to branch on it, something like String.valid?/1 may get you what you want.

Also Liked

brettbeatty

brettbeatty

From the typespec docs

Note that String.t() and binary() are equivalent to analysis tools. Although, for those reading the documentation, String.t() implies it is a UTF-8 encoded binary.

Let’s say you have two binaries:

iex(1)> <<0, 0, 0>>
<<0, 0, 0>>
iex(2)> <<?a, ?b, ?c>>
"abc"

binary() would describe both of them, but String.t() would only apply to "abc". Tooling, however, doesn’t differentiate at the type level because String.t() is just an alias for binary().

Base.url_encode64 just converts any binary, which could be a human-readable string, to a URL-encoded Base64 string, which is for sure a UTF-8 encoded binary.

c4710n

c4710n

The reason is that string is actually a binary - a UTF-8 encoded binary.

edit: String.valid?/1, like @brettbeatty said.

Base.url_encode64 is not for converting between binaries and strings. It is for encoding a binary into a base64 encoded string, which can be used as a part of a valid URL.

In practice, I am using typespecs to tell my API consumers the accurate information about the public interfaces. For example:

@spec hello(String.t()) :: String.t()
def hello(message), do: message

If you see the the source code of String module, it is using the same method. For example:

@spec split(t, pattern | Regex.t(), keyword) :: [t]
def split(string, pattern, options \\ [])

def split(string, %Regex{} = pattern, options) when is_binary(string) and is_list(options) do
  Regex.split(pattern, string, options)
end

You can see the guard is_binary(string) - I think this is the official way to do string checking.

Maybe, you can just follow this convention for now. :wink:

Where Next?

Popular in Questions Top

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement