eliminate @trusted hack in dyaml.emitter (#199)
eliminate @trusted hack in dyaml.emitter merged-on-behalf-of: BBasile <BBasile@users.noreply.github.com>
This commit is contained in:
parent
0a4057472a
commit
9c2ae02792
|
@ -87,11 +87,14 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
///Stream to write to.
|
||||
Range stream_;
|
||||
|
||||
/// Type used for upcoming emitter steps
|
||||
alias EmitterFunction = void function(typeof(this)*) @safe;
|
||||
|
||||
///Stack of states.
|
||||
Appender!(void function() @safe[]) states_;
|
||||
Appender!(EmitterFunction[]) states_;
|
||||
|
||||
///Current state.
|
||||
//WARNING! DO NOT CALL DIRECTLY! Use callNext() instead!
|
||||
void function() @safe state_;
|
||||
EmitterFunction state_;
|
||||
|
||||
///Event queue.
|
||||
Queue!Event events_;
|
||||
|
@ -172,13 +175,13 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
* lineBreak = Line break character/s.
|
||||
*/
|
||||
this(Range stream, const bool canonical, const int indent, const int width,
|
||||
const LineBreak lineBreak) @trusted
|
||||
const LineBreak lineBreak) @safe
|
||||
{
|
||||
states_.reserve(32);
|
||||
indents_.reserve(32);
|
||||
stream_ = stream;
|
||||
canonical_ = canonical;
|
||||
nextExpected(&expectStreamStart);
|
||||
nextExpected!"expectStreamStart"();
|
||||
|
||||
if(indent > 1 && indent < 10){bestIndent_ = indent;}
|
||||
if(width > bestIndent_ * 2) {bestWidth_ = width;}
|
||||
|
@ -201,7 +204,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
|
||||
private:
|
||||
///Pop and return the newest state in states_.
|
||||
void function() @safe popState() @safe
|
||||
EmitterFunction popState() @safe
|
||||
{
|
||||
enforce(states_.data.length > 0,
|
||||
new YAMLException("Emitter: Need to pop a state but there are no states left"));
|
||||
|
@ -210,9 +213,9 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
return result;
|
||||
}
|
||||
|
||||
void pushState(void delegate() @safe func) @trusted
|
||||
void pushState(string D)() @safe
|
||||
{
|
||||
states_ ~= func.funcptr;
|
||||
states_ ~= mixin("function(typeof(this)* self) { self."~D~"(); }");
|
||||
}
|
||||
|
||||
///Pop and return the newest indent in indents_.
|
||||
|
@ -328,7 +331,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
new EmitterException("Expected streamStart, but got " ~ event_.idString));
|
||||
|
||||
writeStreamStart();
|
||||
nextExpected(&expectDocumentStart!(Yes.first));
|
||||
nextExpected!"expectDocumentStart!(Yes.first)"();
|
||||
}
|
||||
|
||||
///Expect nothing, throwing if we still have something.
|
||||
|
@ -392,7 +395,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndicator("---", Yes.needWhitespace);
|
||||
if(canonical_){writeIndent();}
|
||||
}
|
||||
nextExpected(&expectRootNode);
|
||||
nextExpected!"expectRootNode"();
|
||||
}
|
||||
else if(event_.id == EventID.streamEnd)
|
||||
{
|
||||
|
@ -402,7 +405,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndent();
|
||||
}
|
||||
writeStreamEnd();
|
||||
nextExpected(&expectNothing);
|
||||
nextExpected!"expectNothing"();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,13 +421,13 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndicator("...", Yes.needWhitespace);
|
||||
writeIndent();
|
||||
}
|
||||
nextExpected(&expectDocumentStart!(No.first));
|
||||
nextExpected!"expectDocumentStart!(No.first)"();
|
||||
}
|
||||
|
||||
///Handle the root node of a document.
|
||||
void expectRootNode() @safe
|
||||
{
|
||||
pushState(&expectDocumentEnd);
|
||||
pushState!"expectDocumentEnd"();
|
||||
expectNode(Context.root);
|
||||
}
|
||||
|
||||
|
@ -511,7 +514,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndicator("[", Yes.needWhitespace, Yes.whitespace);
|
||||
++flowLevel_;
|
||||
increaseIndent(Yes.flow);
|
||||
nextExpected(&expectFlowSequenceItem!(Yes.first));
|
||||
nextExpected!"expectFlowSequenceItem!(Yes.first)"();
|
||||
}
|
||||
|
||||
///Handle a flow sequence item.
|
||||
|
@ -532,7 +535,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
}
|
||||
static if(!first){writeIndicator(",", No.needWhitespace);}
|
||||
if(canonical_ || column_ > bestWidth_){writeIndent();}
|
||||
pushState(&expectFlowSequenceItem!(No.first));
|
||||
pushState!"expectFlowSequenceItem!(No.first)"();
|
||||
expectSequenceNode();
|
||||
}
|
||||
|
||||
|
@ -544,7 +547,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndicator("{", Yes.needWhitespace, Yes.whitespace);
|
||||
++flowLevel_;
|
||||
increaseIndent(Yes.flow);
|
||||
nextExpected(&expectFlowMappingKey!(Yes.first));
|
||||
nextExpected!"expectFlowMappingKey!(Yes.first)"();
|
||||
}
|
||||
|
||||
///Handle a key in a flow mapping.
|
||||
|
@ -568,13 +571,13 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
if(canonical_ || column_ > bestWidth_){writeIndent();}
|
||||
if(!canonical_ && checkSimpleKey())
|
||||
{
|
||||
pushState(&expectFlowMappingSimpleValue);
|
||||
pushState!"expectFlowMappingSimpleValue"();
|
||||
expectMappingNode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
writeIndicator("?", Yes.needWhitespace);
|
||||
pushState(&expectFlowMappingValue);
|
||||
pushState!"expectFlowMappingValue"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -582,7 +585,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
void expectFlowMappingSimpleValue() @safe
|
||||
{
|
||||
writeIndicator(":", No.needWhitespace);
|
||||
pushState(&expectFlowMappingKey!(No.first));
|
||||
pushState!"expectFlowMappingKey!(No.first)"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -591,7 +594,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
{
|
||||
if(canonical_ || column_ > bestWidth_){writeIndent();}
|
||||
writeIndicator(":", Yes.needWhitespace);
|
||||
pushState(&expectFlowMappingKey!(No.first));
|
||||
pushState!"expectFlowMappingKey!(No.first)"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -603,7 +606,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
const indentless = (context_ == Context.mappingNoSimpleKey ||
|
||||
context_ == Context.mappingSimpleKey) && !indentation_;
|
||||
increaseIndent(No.flow, indentless);
|
||||
nextExpected(&expectBlockSequenceItem!(Yes.first));
|
||||
nextExpected!"expectBlockSequenceItem!(Yes.first)"();
|
||||
}
|
||||
|
||||
///Handle a block sequence item.
|
||||
|
@ -618,7 +621,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
|
||||
writeIndent();
|
||||
writeIndicator("-", Yes.needWhitespace, No.whitespace, Yes.indentation);
|
||||
pushState(&expectBlockSequenceItem!(No.first));
|
||||
pushState!"expectBlockSequenceItem!(No.first)"();
|
||||
expectSequenceNode();
|
||||
}
|
||||
|
||||
|
@ -628,7 +631,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
void expectBlockMapping() @safe
|
||||
{
|
||||
increaseIndent(No.flow);
|
||||
nextExpected(&expectBlockMappingKey!(Yes.first));
|
||||
nextExpected!"expectBlockMappingKey!(Yes.first)"();
|
||||
}
|
||||
|
||||
///Handle a key in a block mapping.
|
||||
|
@ -644,13 +647,13 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeIndent();
|
||||
if(checkSimpleKey())
|
||||
{
|
||||
pushState(&expectBlockMappingSimpleValue);
|
||||
pushState!"expectBlockMappingSimpleValue"();
|
||||
expectMappingNode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
writeIndicator("?", Yes.needWhitespace, No.whitespace, Yes.indentation);
|
||||
pushState(&expectBlockMappingValue);
|
||||
pushState!"expectBlockMappingValue"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -658,7 +661,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
void expectBlockMappingSimpleValue() @safe
|
||||
{
|
||||
writeIndicator(":", No.needWhitespace);
|
||||
pushState(&expectBlockMappingKey!(No.first));
|
||||
pushState!"expectBlockMappingKey!(No.first)"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -667,7 +670,7 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
{
|
||||
writeIndent();
|
||||
writeIndicator(":", Yes.needWhitespace, No.whitespace, Yes.indentation);
|
||||
pushState(&expectBlockMappingKey!(No.first));
|
||||
pushState!"expectBlockMappingKey!(No.first)"();
|
||||
expectMappingNode();
|
||||
}
|
||||
|
||||
|
@ -1294,21 +1297,17 @@ struct Emitter(Range, CharType) if (isOutputRange!(Range, CharType))
|
|||
writeString(prefix);
|
||||
writeLineBreak();
|
||||
}
|
||||
|
||||
void nextExpected(void delegate() @safe func) @trusted
|
||||
void nextExpected(string D)() @safe
|
||||
{
|
||||
state_ = func.funcptr;
|
||||
state_ = mixin("function(typeof(this)* self) { self."~D~"(); }");
|
||||
}
|
||||
void nextExpected(void function() @safe func) @safe
|
||||
void nextExpected(EmitterFunction f) @safe
|
||||
{
|
||||
state_ = func;
|
||||
state_ = f;
|
||||
}
|
||||
void callNext() @trusted
|
||||
void callNext() @safe
|
||||
{
|
||||
void delegate() @safe func;
|
||||
func.funcptr = state_;
|
||||
func.ptr = &this;
|
||||
func();
|
||||
state_(&this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue