--[[
	A 'Symbol' is an opaque marker type that can be used to signify unique
	statuses. Symbols have the type 'userdata', but when printed to the console,
	the name of the symbol is shown.
]]

local Symbol = {}

--[[
	Creates a Symbol with the given name.

	When printed or coerced to a string, the symbol will turn into the string
	given as its name.
]]
function Symbol.named(name)
	assert(type(name) == "string", "Symbols must be created using a string name!")

	local self = newproxy(true)

	local wrappedName = ("Symbol(%s)"):format(name)

	getmetatable(self).__tostring = function()
		return wrappedName
	end

	return self
end

--[[
	Create an unnamed Symbol. Usually, you should create a named Symbol using
	Symbol.named(name)
]]
function Symbol.unnamed()
	local self = newproxy(true)

	getmetatable(self).__tostring = function()
		return "Unnamed Symbol"
	end

	return self
end

return Symbol