Skip to content

Commit

Permalink
Tidy source code with tidy.R
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroen committed Dec 6, 2013
1 parent 7287acf commit ea7e685
Show file tree
Hide file tree
Showing 40 changed files with 800 additions and 928 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
@@ -1,5 +1,5 @@
Package: jsonlite
Version: 0.9.0
Version: 0.9.0.99
Title: Convert R objects to JSON and vice versa
License: Apache License (== 2.0)
NeedsCompilation: yes
Expand Down
22 changes: 11 additions & 11 deletions R/as.iso.R
@@ -1,19 +1,19 @@
as.iso <- function(x, ...){
UseMethod("as.iso");
as.iso <- function(x, ...) {
UseMethod("as.iso")
}

#' @method as.iso Date
#' @S3method as.iso Date
as.iso.Date <- function(x, ...){
as.character(x);
as.iso.Date <- function(x, ...) {
as.character(x)
}

#' @method as.iso POSIXt
#' @S3method as.iso POSIXt
as.iso.POSIXt <- function(x, UTC=FALSE, ...){
if(isTRUE(UTC)){
as.character(x, format="%Y-%m-%dT%H:%M:%SZ", tz="UTC");
} else {
as.character(x, format="%Y-%m-%dT%H:%M:%S");
}
}
as.iso.POSIXt <- function(x, UTC = FALSE, ...) {
if (isTRUE(UTC)) {
as.character(x, format = "%Y-%m-%dT%H:%M:%SZ", tz = "UTC")
} else {
as.character(x, format = "%Y-%m-%dT%H:%M:%S")
}
}
34 changes: 17 additions & 17 deletions R/as.scalar.R
Expand Up @@ -8,20 +8,20 @@
#' @author Jeroen Ooms \email{jeroen.ooms@@stat.ucla.edu}
#' @examples toJSON(list(foo=123));
#' toJSON(list(foo=as.scalar(123)));
as.scalar <- function(obj){
#Lists can never be a scalar (this can arise if a dataframe contains a column with lists)
if(is.data.frame(obj)){
if(nrow(obj) > 1){
warning("as.scalar was applied to dataframe with more than 1 row.")
return(obj);
}
} else {
if(length(obj) > 1){
warning("as.scalar was applied to an object of length > 1.")
return(obj);
}
}

class(obj) <- c("scalar",class(obj));
return(obj);
}
as.scalar <- function(obj) {
# Lists can never be a scalar (this can arise if a dataframe contains a column with lists)
if (is.data.frame(obj)) {
if (nrow(obj) > 1) {
warning("as.scalar was applied to dataframe with more than 1 row.")
return(obj)
}
} else {
if (length(obj) > 1) {
warning("as.scalar was applied to an object of length > 1.")
return(obj)
}
}
class(obj) <- c("scalar", class(obj))
return(obj)
}
16 changes: 7 additions & 9 deletions R/asJSON.AAAgeneric.R
@@ -1,9 +1,7 @@
setGeneric("asJSON",
function(x, pretty=FALSE, ...){
ans <- standardGeneric("asJSON");
if(isTRUE(pretty)){
ans <-prettify(ans);
}
return(ans);
}
);
setGeneric("asJSON", function(x, pretty = FALSE, ...) {
ans <- standardGeneric("asJSON")
if (isTRUE(pretty)) {
ans <- prettify(ans)
}
return(ans)
})
41 changes: 19 additions & 22 deletions R/asJSON.ANY.R
@@ -1,22 +1,19 @@
setMethod("asJSON", "ANY",
function(x, force=FALSE, ...) {
if(isS4(x) && !is(x, "classRepresentation")) {
if(isTRUE(force)){
return(asJSON(attributes(x), ...));
} else {
stop("No S4 method for object of class:", class(x));
}
} else if(length(class(x)) > 1) {
#If an object has multiple classes, we recursively try the next class.
#This is S3 style dispatching that doesn't work by default for formal method definitions
#There should be a more native way to accomplish this
return(asJSON(structure(x, class=class(x)[-1]), ...));
} else if(isTRUE(force) && existsMethod("asJSON", class(unclass(x)))) {
#As a last resort we can force encoding using the unclassed object
return(asJSON(unclass(x), ...));
} else {
#If even that doesn't work, we give up.
stop("No S3 method asJSON for class: ", class(x));
}
}
);
setMethod("asJSON", "ANY", function(x, force = FALSE, ...) {
if (isS4(x) && !is(x, "classRepresentation")) {
if (isTRUE(force)) {
return(asJSON(attributes(x), ...))
} else {
stop("No S4 method for object of class:", class(x))
}
} else if (length(class(x)) > 1) {
# If an object has multiple classes, we recursively try the next class. This is S3 style dispatching that doesn't work
# by default for formal method definitions There should be a more native way to accomplish this
return(asJSON(structure(x, class = class(x)[-1]), ...))
} else if (isTRUE(force) && existsMethod("asJSON", class(unclass(x)))) {
# As a last resort we can force encoding using the unclassed object
return(asJSON(unclass(x), ...))
} else {
# If even that doesn't work, we give up.
stop("No S3 method asJSON for class: ", class(x))
}
})
24 changes: 9 additions & 15 deletions R/asJSON.Date.R
@@ -1,15 +1,9 @@
setMethod("asJSON", "Date",
function(x, Date=c("ISO8601", "epoch"), ...) {

#Validate argument
Date <- match.arg(Date);

#select a schema
output <- switch(Date,
"ISO8601" = as.iso(x),
"epoch" = unclass(x),
default = stop("Invalid argument for 'Date':", Date)
);
return(asJSON(output, ...));
}
);
setMethod("asJSON", "Date", function(x, Date = c("ISO8601", "epoch"), ...) {

# Validate argument
Date <- match.arg(Date)

# select a schema
output <- switch(Date, ISO8601 = as.iso(x), epoch = unclass(x), default = stop("Invalid argument for 'Date':", Date))
return(asJSON(output, ...))
})
8 changes: 4 additions & 4 deletions R/asJSON.NULL.R
@@ -1,4 +1,4 @@
#Note that this is different from RJSONIO because null values are NA.
setMethod("asJSON", "NULL",
function(x, ...) {return("{}");}
);
# Note that this is different from RJSONIO because null values are NA.
setMethod("asJSON", "NULL", function(x, ...) {
return("{}")
})
63 changes: 31 additions & 32 deletions R/asJSON.POSIXt.R
@@ -1,32 +1,31 @@
setMethod("asJSON", "POSIXt",
function(x, POSIXt = c("string", "ISO8601", "epoch", "mongo"), UTC=FALSE, digits, ...) {
#note: UTC argument doesn't seem to be working consistently
#maybe use ?format instead of ?as.character

#Validate
POSIXt <- match.arg(POSIXt);

#empty vector
if(!length(x)) return("[]");

#Encode based on a schema
if(POSIXt == "mongo"){
if(is(x, "POSIXlt")){
x <- as.POSIXct(x);
}
y <-lapply(as.list(x), function(item){
if(is.na(item)) return(item)
as.scalar(list("$date" = as.scalar(floor((unclass(item)*1000)))));
});
return(asJSON(y, digits=0, ...))
} else if(POSIXt == "ISO8601"){
return(asJSON(as.iso(x, UTC=UTC), ...));
} else if(POSIXt == "string"){
return(asJSON(as.character(x), ...));
} else if(POSIXt == "epoch"){
return(asJSON(floor(unclass(as.POSIXct(x))*1000), digits=digits, ...));
} else {
stop("Invalid value for argument POSIXt:", POSIXt)
}
}
);
setMethod("asJSON", "POSIXt", function(x, POSIXt = c("string", "ISO8601", "epoch", "mongo"), UTC = FALSE, digits, ...) {
# note: UTC argument doesn't seem to be working consistently maybe use ?format instead of ?as.character

# Validate
POSIXt <- match.arg(POSIXt)

# empty vector
if (!length(x))
return("[]")

# Encode based on a schema
if (POSIXt == "mongo") {
if (is(x, "POSIXlt")) {
x <- as.POSIXct(x)
}
y <- lapply(as.list(x), function(item) {
if (is.na(item))
return(item)
as.scalar(list(`$date` = as.scalar(floor((unclass(item) * 1000)))))
})
return(asJSON(y, digits = 0, ...))
} else if (POSIXt == "ISO8601") {
return(asJSON(as.iso(x, UTC = UTC), ...))
} else if (POSIXt == "string") {
return(asJSON(as.character(x), ...))
} else if (POSIXt == "epoch") {
return(asJSON(floor(unclass(as.POSIXct(x)) * 1000), digits = digits, ...))
} else {
stop("Invalid value for argument POSIXt:", POSIXt)
}
})
57 changes: 28 additions & 29 deletions R/asJSON.character.R
@@ -1,29 +1,28 @@
setMethod("asJSON", "character",
function(x, container = TRUE, na=c("default", "null", "string"), ...) {

#0 vector is not handled properly by paste()
if(!length(x)) return("[]");

#vectorized escaping
tmp <- deparse_vector(x)

#validate NA
na <- match.arg(na);
if(na %in% c("default", "null")){
tmp[is.na(x)] <- "null";
} else {
tmp[is.na(x)] <- "\"NA\"";
}

#collapse
tmp <- paste(tmp, collapse = ", ")

#this is almost always true, except for class 'scalar'
if(container) {
tmp <- paste("[", tmp, "]");
}

#return
return(tmp);
}
);
setMethod("asJSON", "character", function(x, container = TRUE, na = c("default", "null", "string"), ...) {

# 0 vector is not handled properly by paste()
if (!length(x))
return("[]")

# vectorized escaping
tmp <- deparse_vector(x)

# validate NA
na <- match.arg(na)
if (na %in% c("default", "null")) {
tmp[is.na(x)] <- "null"
} else {
tmp[is.na(x)] <- "\"NA\""
}

# collapse
tmp <- paste(tmp, collapse = ", ")

# this is almost always true, except for class 'scalar'
if (container) {
tmp <- paste("[", tmp, "]")
}

# return
return(tmp)
})
16 changes: 6 additions & 10 deletions R/asJSON.classRepresentation.R
@@ -1,12 +1,8 @@
#classRepresentation is an object that defines an S4 class
#encoding it usually doesn't serve much purpose, however as
#we don't wnat to encode it as a regular S4 data object.
# classRepresentation is an object that defines an S4 class encoding it usually doesn't serve much purpose, however as
# we don't wnat to encode it as a regular S4 data object.

#it currently only encodes the slots.
#we could add encoding of methods of that would be desired.
# it currently only encodes the slots. we could add encoding of methods of that would be desired.

setMethod("asJSON", "classRepresentation",
function(x, ...) {
return(asJSON(attributes(x)$slots, ...));
}
);
setMethod("asJSON", "classRepresentation", function(x, ...) {
return(asJSON(attributes(x)$slots, ...))
})
63 changes: 31 additions & 32 deletions R/asJSON.complex.R
@@ -1,33 +1,32 @@
setMethod("asJSON", "complex",
function(x, digits=5, container=TRUE, complex=c("string", "list"), na="string", ...) {
#validate
complex <- match.arg(complex);
setMethod("asJSON", "complex", function(x, digits = 5, container = TRUE, complex = c("string", "list"), na = "string",
...) {
# validate
complex <- match.arg(complex)

# empty vector
if (!length(x))
return("[]")

if (complex == "string") {
mystring <- prettyNum(x = x, digits = digits)
if (na == "null") {
mystring[is.na(x)] <- NA
}

#empty vector
if(!length(x)) return("[]");

if(complex == "string"){
mystring <- prettyNum(x=x, digits=digits);
if(na == "null"){
mystring[is.na(x)] <- NA;
}

if(!container){
mystring <- as.scalar(mystring);
}
return(asJSON(mystring, na="null", ...));
} else {
mylist <- list(real=Re(x), imaginary=Im(x));

#this is a bit of a hack
#if container is false, this is length 1 vector
#so we have to actually apply this so the real and imaginary elements of the list
if(!container){
mylist <- lapply(mylist, as.scalar);
}

#return
return(asJSON(mylist, na=na, ...));
}
}
);
if (!container) {
mystring <- as.scalar(mystring)
}
return(asJSON(mystring, na = "null", ...))
} else {
mylist <- list(real = Re(x), imaginary = Im(x))

# this is a bit of a hack if container is false, this is length 1 vector so we have to actually apply this so the real
# and imaginary elements of the list
if (!container) {
mylist <- lapply(mylist, as.scalar)
}

# return
return(asJSON(mylist, na = na, ...))
}
})

0 comments on commit ea7e685

Please sign in to comment.