Permalink
Fetching contributors…
Cannot retrieve contributors at this time
128 lines (108 sloc) 3.65 KB
/* Rosella String Formatting
The routines in this namespace are used with string formatters.
*/
namespace Rosella.StringFormatter
{
/* Type-Specific Formatters
*/
const string TYPE_FORMATTERS = "Rosella.StringFormatter.type_formatters";
// Get a hash of type-specific formatters
function type_formatters()
{
using Rosella.get_pmc_pmc_hash;
return Rosella.Globals.autoget_global(TYPE_FORMATTERS, get_pmc_pmc_hash);
}
// Register a new formatter object for a specific type
function register_type_formatter(var type, var fmt)
{
Rosella.StringFormatter.__verify_formatter(fmt);
var f = Rosella.StringFormatter.type_formatters();
var type_c = Rosella.get_type_class(type);
f[type_c] = fmt;
}
// Search for a formatter for the given type. Return null if none are found.
function get_type_formatter(var type)
{
var type_c = Rosella.get_type_class(type);
var f = Rosella.StringFormatter.type_formatters();
if (exists f[type_c])
return f[type_c];
return null;
}
function autoget_type_formatter(var type, var gen)
{
var type_c = Rosella.get_type_class(type);
var formatters = Rosella.StringFormatter.type_formatters();
if (exists formatters[type_c])
return formatters[type_c];
var f = gen();
Rosella.StringFormatter.__verify_formatter(f);
formatters[type_c] = f;
return f;
}
/* Role-Specific Formatters
*/
const string ROLE_FORMATTERS = "Rosella.StringFormatter.role_formatters";
// Get a hash of role-specific formatters
function role_formatters()
{
return Rosella.Globals.autoget_global(ROLE_FORMATTERS, function() { return {}; });
}
// Register a new formatter object for a named role
function register_role_formatter(string role, var fmt)
{
Rosella.StringFormatter.__verify_formatter(fmt);
var f = Rosella.StringFormatter.role_formatters();
f[role] = fmt;
}
/* Get Formatter
*/
// Get a suitable StringFormatter for the given object
// Check from most specific first to least specific last
function get_formatter(var obj)
{
if (can(obj, "get_string_formatter"))
return obj.get_string_formatter();
var obj_c = typeof(obj);
var type_converters = Rosella.StringFormatter.type_formatters();
if (exists type_converters[obj_c])
return type_converters[obj_c];
var role_converters = Rosella.StringFormatter.role_formatters();
for (string role in role_converters) {
if (does(obj, role))
return role_converters[role];
}
return null;
}
/* Private Helper Routines
*/
// Verify that the given object is an acceptable StringFormatter or
// look-alike
function __verify_formatter(var f)
{
if ((f instanceof Rosella.StringFormatter) || (can(f, "format") && can(f, "format_default")))
return;
Rosella.Error.error("Cannot register string formatter of type %s", typeof(f));
}
}
/* Default StringFormatter
A default StringFormatter which uses sprintf
*/
class Rosella.StringFormatter
{
function StringFormatter() { }
// Create a string from an object and a format string
function format(var obj, string fmt)
{
if (fmt == null || fmt == "")
fmt = "s";
fmt = "%" + fmt;
string r = sprintf(fmt, [obj]);
return r;
}
// Create a string from the object using a default formatting rule
function format_default(var obj)
{
return string(obj);
}
}