104 lines
3.0 KiB
Dart

// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
part of 'pipeline.dart';
class MiddlewareNode {
final Pipeline pipeline;
Middleware? middleware;
late MiddlewareNode _parent;
late MiddlewareNode _child;
final bool _isEnd;
/// Reference to the previous [MiddlewareNode] in the [Pipeline]
MiddlewareNode get parent => _parent;
/// Reference to the next [MiddlewareNode] in the [Pipeline]
MiddlewareNode get child => _child;
/// Whether this is the begin [MiddlewareNode]
bool get isBegin => _parent == this;
/// Whether this is the end [MiddlewareNode]
bool get isEnd => _child == this;
/// Whether this is the first [MiddlewareNode]
bool get isFirst => !isBegin && _parent == pipeline.begin;
/// Whether this is the last [MiddlewareNode]
bool get isLast => !isEnd && _child == pipeline.end;
MiddlewareNode._(
this.pipeline,
this.middleware, {
MiddlewareNode? parent,
MiddlewareNode? child,
}) : _isEnd = false {
_parent = parent ?? this;
_child = child ?? this;
}
MiddlewareNode._end(this.pipeline) : _isEnd = true {
_child = this;
}
MiddlewareNode._begin(this.pipeline) : _isEnd = true {
_parent = this;
}
/// Creates a new [MiddlewareNode] right **before** this in [pipeline]
MiddlewareNode insertBefore(Middleware middleware) {
if (isBegin) {
throw StateError(
'A MiddlewareNode cannot be inserted '
'before begin MiddlewareNode',
);
}
final newMiddlewareNode =
MiddlewareNode._(pipeline, middleware, parent: _parent, child: this);
_parent._child = newMiddlewareNode;
_parent = newMiddlewareNode;
pipeline._length++;
return newMiddlewareNode;
}
/// Creates a new [MiddlewareNode] right **after** this in [pipeline]
MiddlewareNode insertAfter(Middleware middleware) {
if (isEnd) {
throw StateError(
'A MiddlewareNode cannot be inserted '
'after end MiddlewareNode',
);
}
final newMiddlewareNode =
MiddlewareNode._(pipeline, middleware, parent: this, child: _child);
_child._parent = newMiddlewareNode;
_child = newMiddlewareNode;
pipeline._length++;
return newMiddlewareNode;
}
MiddlewareNode remove() {
if (_isEnd) throw StateError('Cannot remove end MiddlewareNode');
_child._parent = _parent;
_parent._child = _child;
pipeline._length--;
return child;
}
}