i have a protocol HTTP.ServerLoop that has some requirements and provides a method runServer()
public protocol ServerLoop
{
func allow(origin:IP) -> Bool
func x()
func y()
}
extension HTTP.ServerLoop
{
func runServer()
}
there is an actor SharedServer that provides all the witnesses except for allow(origin:), and lives in a module called CoreServer. the idea is that a downstream module will extend SharedServer with the necessary allow(origin:) requirement and declare the ServerLoop conformance.
there are two such modules, a public module with a stub implementation, and a private module that provides a proprietary implementation.
public module:
import CoreServer
extension SharedServer:HTTP.ServerLoop
{
public
func allow(origin:IP) -> Bool
{
// Allow everything.
return true
}
}
proprietary module:
import CoreServer
extension SharedServer:HTTP.ServerLoop
{
public
func allow(origin:IP) -> Bool
{
// Enforce firewall rules
...
}
}
now, i would like to write some extension in the CoreServer module that assumes a conformance that does not yet exist at this level.
extension SharedServer where Self:HTTP.ServerLoop
{
public
func run() async throws
{
// calls `runServer()`
}
}
but it seems this is not allowed.
trailing 'where' clause for extension of non-generic type 'Unidoc.ServerLoop'
this run() method accesses a lot of private implementation details of SharedServer. so it is not a good candidate for refactoring into some SharedServerProtocol. are there any other ways to assume a conformance that is expected to be declared in a client module?