Q:

Permutation Encoding

Write a program which can encode text to avoid reusing characters, and convert back.
Both normal and encoded forms are restricted to a particular character set: the space character  with code point 32, the tilde character ~ with code point 126, and all characters between. This is 95 total characters. It's a printable subset of ASCII.
The encoded text can be up to 95 characters long. The normal text can be up to 75 characters long, because above 75 it would be impossible to uniquely encode all messages.
Encoding
There are some requirements for the encoding:

Uses only characters from the character set described above
Uses each character at most once
Uniquely encodes all valid messages

Other than that, you're free to pick any variant.
Input
Input will consist of 2 items:

A boolean: false to encode, true to decode
A string: the message to be encoded/decoded

How you receive the input is up to you.
The boolean can be as a boolean or integer in the range [-2, 2] in your language's format. If the esoteric language doesn't have booleans or integers, use the closest analogue. I'm not doing the "or any 2 distinct values" because then you could use an encoding and decoding program as the values and evaluate them.
Output
Output should consist of only the encoded/decoded string. Leading and trailing newlines are okay.
Scoring
Your score is the length of your program, shorter is better.
I still encourage you to try harder languages even if they won't win.
Testing
Testing will generally be done with Try it Online!. For convenience, please provide a link to your program with some test input already filled in.
These are the steps to test a program:

Pick a valid normal string.
Encode it using the program.
Check that the encoded form is valid.
Decode it using the program.
Check that the final result matches the original string.

This can be repeated with other test strings for confidence.
If you show a working case and no failing cases have been found, we will assume your program works.
Reference Implementation
I am providing a reference implementation that shows one possible method, in hopes of making this problem more approachable. I used it to generate the examples. I recommend you try the problem yourself before looking at how I did it, that way you may independently come up with a better mapping.
Examples
Since you can choose a different encoding, as well as different input/output methods, your program might not match these examples.
Empty

Input:
0

Output:
(none)
Input:
1

Output:
(none)

Small

Input:
0
Hello, world!

Output:
 #mvcD_YnEeX5?

Input:
1
 #mvcD_YnEeX5?

Output:
Hello, world!

Max Size

Input:
0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Output:
C-,y=6Js?3TOISp+975zk}.cwV|{iDjKmd[:/]$Q1~G8vAneoh #&<LYMPNZB_x;2l*r^(4E'tbU@q>a!\WHuRFg0"f%X`)

Input:
1
C-,y=6Js?3TOISp+975zk}.cwV|{iDjKmd[:/]$Q1~G8vAneoh #&<LYMPNZB_x;2l*r^(4E'tbU@q>a!\WHuRFg0"f%X`)

Output:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Extras
How did I get the 75 characters limit? I could have brute force checked it of course, but there's a slightly more mathematical method for counting the number of possible encoded messages for a given character set:
$$
F(n)=\sum_{k=0}^{n}{\frac{n!}{(n-k)!}}=e\Gamma(n+1,1)\approx en!
$$
Here are the relevant bounds. There's plenty more valid encoded messages than normal messages, but still enough normal messages that you'll need a variable length encoding.
$$
F(95)\approx 2.81\times 10^{148} \\
{95}^{75}\approx 2.13\times 10^{148} \\
95!\approx 1.03\times 10^{148}
$$
The problem was inspired by a phenomenon on the Discord chat platform. In Discord, you can "react" to chat messages, which adds a little emoji underneath. You can react many times on a single chat message. Each emoji can only be added once. They remember the order they were added and display oldest to newest, left to right. You can add some non-emojis too. People sometimes write short messages in reactions, and when their message has repeat characters they're forced to get creative, usually they opt for lookalike characters.

A:

Python 3, 339 338 bytes
lambda b,s:b and G(f(s))or F(g(s))
a=''.join(chr(32+i)for i in range(95))
f=lambda s:95*f(s[1:])+ord(s[0])-31if s else 0
F=lambda n:chr((n-1)%95+32)+F((n-1)//95)if n else ''
g=lambda s,d=a:1+d.find(s[0])+len(d)*g(s[1:],d.replace(s[0],''))if s else 0
G=lambda n,d=a:d[(n-1)%len(d)]+G((n-1)//len(d),d.replace(d[(n-1)%len(d)],''))if n else''

Try it online!
Same length, uses a list instead of a string for the ASCII chars Try it online!.
Overview: WIP

Because the number of printable ASCII strings with 75 or fewer characters is 21570794844237986466892014672640809417999612393958961235356099871415520891159490775110725336452276983325050565474469409911975201387750975629116626495, which is less than the number of valid encoded strings (28079792812953073919740255779032193344167751681188124122118245935431845577725060598682278885127314791932249387894125026034584206856782082066829102875)

All we need to do is theoretically sort the valid encoded strings and the valid non-encoded strings, take the index in the correct list of our given input, then return the string at that index in the other list.

f: Converts an input (non-encoded) string to an integer based on its index in the theoretical list of ASCII strings sorted by length and then lexicographically. 

The empty string is 0
Single-char strings are 1 to 95
Two-char strings are 96 to 9120, etc.

F: Undoes f, converts an integer to a (non-encoded) string.
g: Converts an input (encoded) string to an integer (<= 28079792812953073919740255779032193344167751681188124122118245935431845577725060598682278885127314791932249387894125026034584206856782082066829102875 for valid inputs) based on its index in the theoretical list of valid encoded strings sorted by length and then lexicographically. 

The empty string is 0
Single-char strings are 1 to 95
Two-char strings are 96 to 9025, etc.

G: undoes g, converts an integer to an (encoded) string.
Main function: Unnamed lambda b,s:b and G(f(s))or F(g(s)): Uses the boolean b to determine whether to encode G(f(s)) or decode F(g(s)) the string, and does so.

