I'd be interested to hear of problems and/or improvements to this idea.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.gilstraps.lambdaplay; | |
public class Either<V> { | |
private final V val; | |
private final Exception ex; | |
public Either(V aNR) { | |
if (aNR == null) throw new NullPointerException("Must have either a hasValue or an error."); | |
val = aNR; | |
ex = null; | |
} | |
public Either(Exception anE) { | |
if (anE == null) throw new NullPointerException("Must have either a hasValue or an error."); | |
val = null; | |
ex = anE; | |
} | |
public boolean hasValue() { | |
return val != null; | |
} | |
public V right() { | |
return val; | |
} | |
public V getOrElse( final V defaultValue ) { | |
return hasValue() ? val : defaultValue; | |
} | |
public Exception left() { | |
return ex; | |
} | |
public interface Map<S, T> { | |
public T map(final S s); | |
} | |
public <O> Either<O> rightMap(Map<V, O> m) { | |
if (hasValue()) { | |
try { | |
return new Either<O>(m.map(this.val)); | |
} | |
catch (Exception e) { | |
return new Either<O>(e); | |
} | |
} | |
return new Either<O>(ex); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.gilstraps.lambdaplay; | |
import org.junit.Test; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertTrue; | |
public class EitherTests { | |
static final String USER_NAME = "username"; | |
static final String ROOT = "root"; | |
static class AuthLevel { | |
} | |
static final AuthLevel GUEST = new AuthLevel(); | |
static final AuthLevel USER = new AuthLevel(); | |
static final AuthLevel SUPERUSER = new AuthLevel(); | |
public static class NoSuchUserException extends Exception { | |
} | |
public static class UnknownSettingException extends Exception { | |
} | |
public static class SettingGetter { | |
private String userName; | |
public SettingGetter(final String name) { | |
userName = name; | |
} | |
Either<String> get_setting(final String settingName) { | |
// Simple way to test out both having and not having a username | |
if (settingName.equals(USER_NAME)) { | |
if (userName != null) { return new Either<>(userName); } | |
else { return new Either<>(new NoSuchUserException()); } | |
} | |
else return new Either<>(new UnknownSettingException()); | |
} | |
} | |
public static class Authorizer { | |
public AuthLevel getAuthorizationLevelForUser(final String user) { | |
if ( ROOT.equals(user) ) { | |
return SUPERUSER; | |
} | |
else { | |
return USER; | |
} | |
} | |
} | |
public static class Decider { | |
public Boolean canDoAnything( final AuthLevel l ) { | |
return SUPERUSER.equals(l); | |
} | |
} | |
@Test | |
public void authLevelTests() { | |
{ | |
final SettingGetter sg = new SettingGetter("joe"); | |
final Authorizer authorizer = new Authorizer(); | |
final Either<AuthLevel> authLevel = getAuthorizationLevel(sg,authorizer); | |
assertEquals(USER,authLevel.right()); | |
} | |
{ | |
final SettingGetter sg = new SettingGetter(null); | |
final Authorizer authorizer = new Authorizer(); | |
final Either<AuthLevel> authLevel = getAuthorizationLevel(sg,authorizer); | |
assertEquals(null,authLevel.right()); | |
assertEquals(NoSuchUserException.class,authLevel.left().getClass()); | |
} | |
{ | |
final SettingGetter sg = new SettingGetter(null); | |
final Authorizer authorizer = new Authorizer(); | |
final Either<AuthLevel> authLevel = getAuthorizationLevel(sg,authorizer); | |
final AuthLevel level = authLevel.getOrElse(GUEST); | |
assertEquals(GUEST,level); | |
} | |
{ | |
final SettingGetter sg = new SettingGetter(ROOT); | |
final Authorizer authorizer = new Authorizer(); | |
final Decider decider = new Decider(); | |
final Either<Boolean> isAllPowerful = sg.get_setting(USER_NAME).rightMap(authorizer::getAuthorizationLevelForUser).rightMap(decider::canDoAnything); | |
assertTrue(isAllPowerful.hasValue()); | |
assertEquals(true, isAllPowerful.right() ); | |
} | |
} | |
public Either<AuthLevel> getAuthorizationLevel(final SettingGetter sg, final Authorizer authorizer ) { | |
Either<String> possibleUser = sg.get_setting(USER_NAME); | |
return possibleUser.rightMap(authorizer::getAuthorizationLevelForUser); | |
} | |
} |
No comments:
Post a Comment