Skip to content

Commit

Permalink
Promote Emitter exceptions to asserts or contracts (#246)
Browse files Browse the repository at this point in the history
* promote emitter exceptions to asserts

* convert many emitter asserts to in contracts
  • Loading branch information
Herringway authored and Basile-z committed Apr 18, 2019
1 parent d10d2b2 commit 10356c8
Showing 1 changed file with 37 additions and 71 deletions.
108 changes: 37 additions & 71 deletions source/dyaml/emitter.d
Expand Up @@ -35,17 +35,6 @@ import dyaml.tagdirective;

package:

/**
* Exception thrown at Emitter errors.
*
* See_Also:
* YAMLException
*/
class EmitterException : YAMLException
{
mixin ExceptionCtors;
}

//Stores results of analysis of a scalar, determining e.g. what scalar style to use.
struct ScalarAnalysis
{
Expand Down Expand Up @@ -190,7 +179,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
analysis_.flags.isNull = true;
}

///Emit an event. Throws EmitterException on error.
///Emit an event.
void emit(Event event) @safe
{
events_.push(event);
Expand All @@ -205,9 +194,9 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
private:
///Pop and return the newest state in states_.
EmitterFunction popState() @safe
in(states_.data.length > 0,
"Emitter: Need to pop a state but there are no states left")
{
enforce(states_.data.length > 0,
new YAMLException("Emitter: Need to pop a state but there are no states left"));
const result = states_.data[$-1];
states_.shrinkTo(states_.data.length - 1);
return result;
Expand All @@ -220,10 +209,10 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Pop and return the newest indent in indents_.
int popIndent() @safe
in(indents_.data.length > 0,
"Emitter: Need to pop an indent level but there" ~
" are no indent levels left")
{
enforce(indents_.data.length > 0,
new YAMLException("Emitter: Need to pop an indent level but there" ~
" are no indent levels left"));
const result = indents_.data[$-1];
indents_.shrinkTo(indents_.data.length - 1);
return result;
Expand All @@ -232,26 +221,19 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
///Write a string to the file/stream.
void writeString(const scope char[] str) @safe
{
try
static if(is(CharType == char))
{
static if(is(CharType == char))
{
copy(str, stream_);
}
static if(is(CharType == wchar))
{
const buffer = to!wstring(str);
copy(buffer, stream_);
}
static if(is(CharType == dchar))
{
const buffer = to!dstring(str);
copy(buffer, stream_);
}
copy(str, stream_);
}
static if(is(CharType == wchar))
{
const buffer = to!wstring(str);
copy(buffer, stream_);
}
catch(Exception e)
static if(is(CharType == dchar))
{
throw new EmitterException("Unable to write to stream: " ~ e.msg);
const buffer = to!dstring(str);
copy(buffer, stream_);
}
}

Expand Down Expand Up @@ -304,9 +286,8 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Determines if the type of current event is as specified. Throws if no event.
bool eventTypeIs(in EventID id) const pure @safe
in(!event_.isNull, "Expected an event, but no event is available.")
{
enforce(!event_.isNull,
new EmitterException("Expected an event, but no event is available."));
return event_.id == id;
}

Expand All @@ -318,9 +299,9 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Handle start of a file/stream.
void expectStreamStart() @safe
in(eventTypeIs(EventID.streamStart),
"Expected streamStart, but got " ~ event_.idString)
{
enforce(eventTypeIs(EventID.streamStart),
new EmitterException("Expected streamStart, but got " ~ event_.idString));

writeStreamStart();
nextExpected!"expectDocumentStart!(Yes.first)"();
Expand All @@ -329,17 +310,16 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
///Expect nothing, throwing if we still have something.
void expectNothing() @safe
{
throw new EmitterException("Expected nothing, but got " ~ event_.idString);
assert(0, "Expected nothing, but got " ~ event_.idString);
}

//Document handlers.

///Handle start of a document.
void expectDocumentStart(Flag!"first" first)() @safe
in(eventTypeIs(EventID.documentStart) || eventTypeIs(EventID.streamEnd),
"Expected documentStart or streamEnd, but got " ~ event_.idString)
{
enforce(eventTypeIs(EventID.documentStart) || eventTypeIs(EventID.streamEnd),
new EmitterException("Expected documentStart or streamEnd, but got "
~ event_.idString));

if(event_.id == EventID.documentStart)
{
Expand Down Expand Up @@ -403,9 +383,9 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Handle end of a document.
void expectDocumentEnd() @safe
in(eventTypeIs(EventID.documentEnd),
"Expected DocumentEnd, but got " ~ event_.idString)
{
enforce(eventTypeIs(EventID.documentEnd),
new EmitterException("Expected DocumentEnd, but got " ~ event_.idString));

writeIndent();
if(event_.explicitDocument)
Expand Down Expand Up @@ -477,14 +457,14 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
}
break;
default:
throw new EmitterException("Expected alias_, scalar, sequenceStart or " ~
assert(0, "Expected alias_, scalar, sequenceStart or " ~
"mappingStart, but got: " ~ event_.idString);
}
}
///Handle an alias.
void expectAlias() @safe
in(event_.anchor != "", "Anchor is not specified for alias")
{
enforce(event_.anchor !is null, new EmitterException("Anchor is not specified for alias"));
processAnchor("*");
nextExpected(popState());
}
Expand Down Expand Up @@ -811,7 +791,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
return;
}

enforce(tag !is null, new EmitterException("Tag is not specified"));
assert(tag != "", "Tag is not specified");
if(preparedTag_ is null){preparedTag_ = prepareTag(tag);}
if(preparedTag_ !is null && preparedTag_ != "")
{
Expand Down Expand Up @@ -865,9 +845,9 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Prepare YAML version string for output.
static string prepareVersion(const string YAMLVersion) @safe
in(YAMLVersion.split(".")[0] == "1",
"Unsupported YAML version: " ~ YAMLVersion)
{
enforce(YAMLVersion.split(".")[0] == "1",
new EmitterException("Unsupported YAML version: " ~ YAMLVersion));
return YAMLVersion;
}

Expand All @@ -885,25 +865,17 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Prepare tag directive handle for output.
static string prepareTagHandle(const string handle) @safe
in(handle != "", "Tag handle must not be empty")
in(handle.drop(1).dropBack(1).all!(c => isAlphaNum(c) || c.among!('-', '_')),
"Tag handle contains invalid characters")
{
enforce(handle !is null && handle != "",
new EmitterException("Tag handle must not be empty"));

if(handle.length > 1) foreach(const dchar c; handle[1 .. $ - 1])
{
enforce(isAlphaNum(c) || c.among!('-', '_'),
new EmitterException("Invalid character: " ~ to!string(c) ~
" in tag handle " ~ handle));
}
return handle;
}

///Prepare tag directive prefix for output.
static string prepareTagPrefix(const string prefix) @safe
in(prefix != "", "Tag prefix must not be empty")
{
enforce(prefix !is null && prefix != "",
new EmitterException("Tag prefix must not be empty"));

auto appender = appender!string();
const int offset = prefix[0] == '!';
size_t start, end;
Expand All @@ -930,8 +902,8 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Prepare tag for output.
string prepareTag(in string tag) @safe
in(tag != "", "Tag must not be empty")
{
enforce(tag !is null, new EmitterException("Tag must not be empty"));

string tagString = tag;
if(tagString == "!"){return tagString;}
Expand Down Expand Up @@ -976,16 +948,10 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))

///Prepare anchor for output.
static string prepareAnchor(const string anchor) @safe
in(anchor != "", "Anchor must not be empty")
in(anchor.all!(c => isAlphaNum(c) || c.among!('-', '_')), "Anchor contains invalid characters")
{
enforce(anchor != "",
new EmitterException("Anchor must not be empty"));
const str = anchor;
foreach(const dchar c; str)
{
enforce(isAlphaNum(c) || c.among!('-', '_'),
new EmitterException("Invalid character: " ~ to!string(c) ~ " in anchor: " ~ str));
}
return str;
return anchor;
}

///Analyze specifed scalar and return the analysis result.
Expand Down

0 comments on commit 10356c8

Please sign in to comment.