waargonaut 0.5.2.2 → 0.6.0.0
raw patch · 69 files changed
+3040/−1802 lines, 69 filesdep +tasty-goldendep +unordered-containersdep ~filepathPVP ok
version bump matches the API change (PVP)
Dependencies added: tasty-golden, unordered-containers
Dependency ranges changed: filepath
API changes (from Hackage documentation)
- Waargonaut.Decode: overrideParser :: Monad f => ParseFn -> DecodeResult f a -> DecodeResult f a
- Waargonaut.Decode: parseWith :: (CharParsing f, Show e) => (f a -> i -> Either e a) -> f a -> i -> Either DecodeError a
- Waargonaut.Decode: runDecode :: Monad f => Decoder f a -> ParseFn -> JCurs -> f (Either (DecodeError, CursorHistory) a)
- Waargonaut.Decode: runDecodeResult :: Monad f => ParseFn -> DecodeResult f a -> f (Either (DecodeError, CursorHistory) a)
- Waargonaut.Decode: runPureDecode :: Decoder Identity a -> ParseFn -> JCurs -> Either (DecodeError, CursorHistory) a
- Waargonaut.Decode: simpleDecode :: Decoder Identity a -> ParseFn -> ByteString -> Either (DecodeError, CursorHistory) a
- Waargonaut.Decode: type ParseFn = ByteString -> Either DecodeError Json
- Waargonaut.Encode: simpleEncodeNoSpaces :: Applicative f => Encoder f a -> a -> f Text
- Waargonaut.Encode: simplePureEncodeNoSpaces :: Encoder Identity a -> a -> Text
- Waargonaut.Types.CommaSep: commaBuilder :: Builder
- Waargonaut.Types.CommaSep: commaSeparatedBuilder :: forall ws a. Char -> Char -> (ws -> Builder) -> (a -> Builder) -> CommaSeparated ws a -> Builder
- Waargonaut.Types.CommaSep: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.CommaSep.Elem f ws a)
- Waargonaut.Types.CommaSep: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.CommaSep.Elem f ws a)
- Waargonaut.Types.CommaSep: instance (GHC.Base.Monoid ws, GHC.Base.Applicative f) => GHC.Base.Applicative (Waargonaut.Types.CommaSep.Elem f ws)
- Waargonaut.Types.CommaSep: instance (GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.CommaSep.Elems ws a)
- Waargonaut.Types.CommaSep: instance (GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.CommaSep.Elems ws a)
- Waargonaut.Types.CommaSep: instance Data.Bifoldable.Bifoldable Waargonaut.Types.CommaSep.Elems
- Waargonaut.Types.CommaSep: instance Data.Bifunctor.Bifunctor Waargonaut.Types.CommaSep.Elems
- Waargonaut.Types.CommaSep: instance Data.Bitraversable.Bitraversable Waargonaut.Types.CommaSep.Elems
- Waargonaut.Types.CommaSep: instance Data.Foldable.Foldable (Waargonaut.Types.CommaSep.Elem f ws)
- Waargonaut.Types.CommaSep: instance Data.Foldable.Foldable (Waargonaut.Types.CommaSep.Elems ws)
- Waargonaut.Types.CommaSep: instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Waargonaut.Types.CommaSep.Elem f)
- Waargonaut.Types.CommaSep: instance Data.Traversable.Traversable (Waargonaut.Types.CommaSep.Elem f ws)
- Waargonaut.Types.CommaSep: instance Data.Traversable.Traversable (Waargonaut.Types.CommaSep.Elems ws)
- Waargonaut.Types.CommaSep: instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Waargonaut.Types.CommaSep.Elem f)
- Waargonaut.Types.CommaSep: instance GHC.Base.Functor (Waargonaut.Types.CommaSep.Elem f ws)
- Waargonaut.Types.CommaSep: instance GHC.Base.Functor (Waargonaut.Types.CommaSep.Elems ws)
- Waargonaut.Types.CommaSep: instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Waargonaut.Types.CommaSep.Elem f)
- Waargonaut.Types.CommaSep: instance GHC.Base.Monoid ws => GHC.Base.Applicative (Waargonaut.Types.CommaSep.Elems ws)
- Waargonaut.Types.CommaSep: instance GHC.Base.Monoid ws => GHC.Base.Semigroup (Waargonaut.Types.CommaSep.Elems ws a)
- Waargonaut.Types.CommaSep: instance GHC.Classes.Eq Waargonaut.Types.CommaSep.Comma
- Waargonaut.Types.CommaSep: instance GHC.Show.Show Waargonaut.Types.CommaSep.Comma
- Waargonaut.Types.CommaSep: instance Waargonaut.Types.CommaSep.HasElem (Waargonaut.Types.CommaSep.Elem f ws a) f ws a
- Waargonaut.Types.CommaSep: instance Waargonaut.Types.CommaSep.HasElems (Waargonaut.Types.CommaSep.Elems ws a) ws a
- Waargonaut.Types.JArray: jArrayBuilder :: (ws -> Builder) -> ((ws -> Builder) -> a -> Builder) -> JArray ws a -> Builder
- Waargonaut.Types.JChar: Backspace :: JCharEscaped digit
- Waargonaut.Types.JChar: Hex :: (HexDigit4 digit) -> JCharEscaped digit
- Waargonaut.Types.JChar: HexDigit4 :: d -> d -> d -> d -> HexDigit4 d
- Waargonaut.Types.JChar: JCharUnescaped :: Char -> JCharUnescaped
- Waargonaut.Types.JChar: QuotationMark :: JCharEscaped digit
- Waargonaut.Types.JChar: ReverseSolidus :: JCharEscaped digit
- Waargonaut.Types.JChar: Solidus :: JCharEscaped digit
- Waargonaut.Types.JChar: WhiteSpace :: Whitespace -> JCharEscaped digit
- Waargonaut.Types.JChar: _Backspace :: AsJCharEscaped r digit => Prism' r ()
- Waargonaut.Types.JChar: _Hex :: AsJCharEscaped r digit => Prism' r (HexDigit4 digit)
- Waargonaut.Types.JChar: _JCharEscaped :: AsJCharEscaped r digit => Prism' r (JCharEscaped digit)
- Waargonaut.Types.JChar: _JCharUnescaped :: AsJCharUnescaped a => Prism' a JCharUnescaped
- Waargonaut.Types.JChar: _QuotationMark :: AsJCharEscaped r digit => Prism' r ()
- Waargonaut.Types.JChar: _ReverseSolidus :: AsJCharEscaped r digit => Prism' r ()
- Waargonaut.Types.JChar: _Solidus :: AsJCharEscaped r digit => Prism' r ()
- Waargonaut.Types.JChar: _WhiteSpace :: AsJCharEscaped r digit => Prism' r Whitespace
- Waargonaut.Types.JChar: class AsJCharEscaped r digit | r -> digit
- Waargonaut.Types.JChar: class AsJCharUnescaped a
- Waargonaut.Types.JChar: class HasHexDigit4 c d | c -> d
- Waargonaut.Types.JChar: data HexDigit4 d
- Waargonaut.Types.JChar: data JCharEscaped digit
- Waargonaut.Types.JChar: hexDigit4 :: HasHexDigit4 c d => Lens' c (HexDigit4 d)
- Waargonaut.Types.JChar: instance (Waargonaut.Types.JChar.JCharUnescaped ~ t) => Control.Lens.Wrapped.Rewrapped Waargonaut.Types.JChar.JCharUnescaped t
- Waargonaut.Types.JChar: instance Control.Lens.Wrapped.Wrapped Waargonaut.Types.JChar.JCharUnescaped
- Waargonaut.Types.JChar: instance Data.Foldable.Foldable Waargonaut.Types.JChar.HexDigit4
- Waargonaut.Types.JChar: instance Data.Foldable.Foldable Waargonaut.Types.JChar.JCharEscaped
- Waargonaut.Types.JChar: instance Data.Traversable.Traversable Waargonaut.Types.JChar.HexDigit4
- Waargonaut.Types.JChar: instance Data.Traversable.Traversable Waargonaut.Types.JChar.JCharEscaped
- Waargonaut.Types.JChar: instance GHC.Base.Functor Waargonaut.Types.JChar.HexDigit4
- Waargonaut.Types.JChar: instance GHC.Base.Functor Waargonaut.Types.JChar.JCharEscaped
- Waargonaut.Types.JChar: instance GHC.Classes.Eq Waargonaut.Types.JChar.JCharUnescaped
- Waargonaut.Types.JChar: instance GHC.Classes.Eq d => GHC.Classes.Eq (Waargonaut.Types.JChar.HexDigit4 d)
- Waargonaut.Types.JChar: instance GHC.Classes.Eq digit => GHC.Classes.Eq (Waargonaut.Types.JChar.JCharEscaped digit)
- Waargonaut.Types.JChar: instance GHC.Classes.Ord Waargonaut.Types.JChar.JCharUnescaped
- Waargonaut.Types.JChar: instance GHC.Classes.Ord d => GHC.Classes.Ord (Waargonaut.Types.JChar.HexDigit4 d)
- Waargonaut.Types.JChar: instance GHC.Classes.Ord digit => GHC.Classes.Ord (Waargonaut.Types.JChar.JCharEscaped digit)
- Waargonaut.Types.JChar: instance GHC.Show.Show Waargonaut.Types.JChar.JCharUnescaped
- Waargonaut.Types.JChar: instance GHC.Show.Show d => GHC.Show.Show (Waargonaut.Types.JChar.HexDigit4 d)
- Waargonaut.Types.JChar: instance GHC.Show.Show digit => GHC.Show.Show (Waargonaut.Types.JChar.JCharEscaped digit)
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJChar GHC.Types.Char Data.Digit.Hexadecimal.MixedCase.HeXDigit
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharEscaped (Waargonaut.Types.JChar.JChar digit) digit
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharEscaped (Waargonaut.Types.JChar.JCharEscaped digit) digit
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharEscaped GHC.Types.Char Data.Digit.Hexadecimal.MixedCase.HeXDigit
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharUnescaped (Waargonaut.Types.JChar.JChar digit)
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharUnescaped GHC.Types.Char
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.AsJCharUnescaped Waargonaut.Types.JChar.JCharUnescaped
- Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.HasHexDigit4 (Waargonaut.Types.JChar.HexDigit4 d) d
- Waargonaut.Types.JChar: jCharBuilderByteStringL :: HeXaDeCiMaL digit => JChar digit -> Builder
- Waargonaut.Types.JChar: jCharBuilderTextL :: HeXaDeCiMaL digit => JChar digit -> Builder
- Waargonaut.Types.JChar: jCharBuilderWith :: (Monoid builder, Semigroup builder, HeXaDeCiMaL digit) => (Char -> builder) -> JChar digit -> builder
- Waargonaut.Types.JChar: newtype JCharUnescaped
- Waargonaut.Types.JChar: parseJCharEscaped :: (CharParsing f, HeXaDeCiMaL digit) => f (JCharEscaped digit)
- Waargonaut.Types.JChar: parseJCharUnescaped :: CharParsing f => f JCharUnescaped
- Waargonaut.Types.JNumber: jNumberBuilder :: JNumber -> Builder
- Waargonaut.Types.JObject: instance (GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.JObject.JAssoc ws a)
- Waargonaut.Types.JObject: instance (GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.JObject.JAssoc ws a)
- Waargonaut.Types.JObject: instance Data.Bifoldable.Bifoldable Waargonaut.Types.JObject.JAssoc
- Waargonaut.Types.JObject: instance Data.Bifunctor.Bifunctor Waargonaut.Types.JObject.JAssoc
- Waargonaut.Types.JObject: instance Data.Bitraversable.Bitraversable Waargonaut.Types.JObject.JAssoc
- Waargonaut.Types.JObject: instance Data.Foldable.Foldable (Waargonaut.Types.JObject.JAssoc ws)
- Waargonaut.Types.JObject: instance Data.Traversable.Traversable (Waargonaut.Types.JObject.JAssoc ws)
- Waargonaut.Types.JObject: instance GHC.Base.Functor (Waargonaut.Types.JObject.JAssoc ws)
- Waargonaut.Types.JObject: instance Waargonaut.Types.JObject.HasJAssoc (Waargonaut.Types.JObject.JAssoc ws a) ws a
- Waargonaut.Types.JObject: jObjectBuilder :: (ws -> Builder) -> ((ws -> Builder) -> a -> Builder) -> JObject ws a -> Builder
- Waargonaut.Types.JString: jStringBuilder :: JString -> Builder
- Waargonaut.Types.Json: waargonautBuilder :: (WS -> Builder) -> Json -> Builder
- Waargonaut.Types.Whitespace: wsBuilder :: WS -> Builder
- Waargonaut.Types.Whitespace: wsRemover :: WS -> Builder
+ Waargonaut.Attoparsec: decodeAttoparsecByteString :: Monad f => Decoder f a -> ByteString -> f (Either (DecodeError, CursorHistory) a)
+ Waargonaut.Attoparsec: decodeAttoparsecText :: Monad f => Decoder f a -> Text -> f (Either (DecodeError, CursorHistory) a)
+ Waargonaut.Attoparsec: pureDecodeAttoparsecByteString :: Decoder Identity a -> ByteString -> Either (DecodeError, CursorHistory) a
+ Waargonaut.Attoparsec: pureDecodeAttoparsecText :: Decoder Identity a -> Text -> Either (DecodeError, CursorHistory) a
+ Waargonaut.Decode: prismDOrFail' :: Monad f => (a -> DecodeError) -> Prism' a b -> Decoder f a -> Decoder f b
+ Waargonaut.Decode.Runners: decodeFromByteString :: (CharParsing f, Monad f, Monad g, Show e) => (forall a. f a -> ByteString -> Either e a) -> Decoder g x -> ByteString -> g (Either (DecodeError, CursorHistory) x)
+ Waargonaut.Decode.Runners: decodeFromString :: (CharParsing f, Monad f, Monad g, Show e) => (forall a. f a -> String -> Either e a) -> Decoder g x -> String -> g (Either (DecodeError, CursorHistory) x)
+ Waargonaut.Decode.Runners: decodeFromText :: (CharParsing f, Monad f, Monad g, Show e) => (forall a. f a -> Text -> Either e a) -> Decoder g x -> Text -> g (Either (DecodeError, CursorHistory) x)
+ Waargonaut.Decode.Runners: decodeWithInput :: (CharParsing f, Show e, Monad g, Monad f) => (forall a. f a -> i -> Either e a) -> (ByteString -> i) -> (i -> ByteString) -> Decoder g x -> i -> g (Either (DecodeError, CursorHistory) x)
+ Waargonaut.Decode.Runners: overrideParser :: (CharParsing g, Monad g, Monad f, Show e) => (forall x. g x -> i -> Either e x) -> (ByteString -> i) -> g Json -> DecodeResult f a -> DecodeResult f a
+ Waargonaut.Decode.Runners: parseWith :: (CharParsing f, Show e) => (f a -> i -> Either e a) -> f a -> i -> Either DecodeError a
+ Waargonaut.Decode.Runners: pureDecodeFromByteString :: (Monad f, CharParsing f, Show e) => (forall a. f a -> ByteString -> Either e a) -> Decoder Identity x -> ByteString -> Either (DecodeError, CursorHistory) x
+ Waargonaut.Decode.Runners: pureDecodeFromString :: (Monad f, CharParsing f, Show e) => (forall a. f a -> String -> Either e a) -> Decoder Identity x -> String -> Either (DecodeError, CursorHistory) x
+ Waargonaut.Decode.Runners: pureDecodeFromText :: (Monad f, CharParsing f, Show e) => (forall a. f a -> Text -> Either e a) -> Decoder Identity x -> Text -> Either (DecodeError, CursorHistory) x
+ Waargonaut.Decode.Runners: pureDecodeWithInput :: (Monad f, CharParsing f, Show e) => (forall g. Monad g => (forall a. f a -> i -> Either e a) -> Decoder g x -> i -> g (Either (DecodeError, CursorHistory) x)) -> (forall a. f a -> i -> Either e a) -> Decoder Identity x -> i -> Either (DecodeError, CursorHistory) x
+ Waargonaut.Decode.Types: mkCursor :: ByteString -> JCurs
+ Waargonaut.Encode: asJson :: Applicative f => Encoder f a -> a -> f Json
+ Waargonaut.Encode: asJson' :: Encoder Identity a -> a -> Json
+ Waargonaut.Encode: simpleEncodeByteString :: Applicative f => Encoder f a -> a -> f ByteString
+ Waargonaut.Encode: simpleEncodeByteStringNoSpaces :: Applicative f => Encoder f a -> a -> f ByteString
+ Waargonaut.Encode: simpleEncodeText :: Applicative f => Encoder f a -> a -> f Text
+ Waargonaut.Encode: simpleEncodeTextNoSpaces :: Applicative f => Encoder f a -> a -> f Text
+ Waargonaut.Encode: simpleEncodeWith :: (Applicative f, Monoid b, IsString t) => Builder t b -> (b -> out) -> (Builder t b -> WS -> b) -> Encoder f a -> a -> f out
+ Waargonaut.Encode: simplePureEncodeByteString :: Encoder Identity a -> a -> ByteString
+ Waargonaut.Encode: simplePureEncodeByteStringNoSpaces :: Encoder Identity a -> a -> ByteString
+ Waargonaut.Encode: simplePureEncodeText :: Encoder Identity a -> a -> Text
+ Waargonaut.Encode: simplePureEncodeTextNoSpaces :: Encoder Identity a -> a -> Text
+ Waargonaut.Encode: simplePureEncodeWith :: (Monoid b, IsString t) => Builder t b -> (b -> out) -> (Builder t b -> WS -> b) -> Encoder Identity a -> a -> out
+ Waargonaut.Encode.Builder: bsBuilder :: Builder ByteString Builder
+ Waargonaut.Encode.Builder: jTypesBuilder :: (IsString t, Monoid b) => Builder t b -> (Builder t b -> WS -> b) -> JType WS Json -> b
+ Waargonaut.Encode.Builder: textBuilder :: Builder Text Builder
+ Waargonaut.Encode.Builder: waargonautBuilder :: (IsString t, Monoid b) => (Builder t b -> WS -> b) -> Builder t b -> Json -> b
+ Waargonaut.Encode.Builder.CommaSep: commaSeparatedBuilder :: forall ws a t b. Monoid b => Builder t b -> Char -> Char -> (Builder t b -> ws -> b) -> (Builder t b -> a -> b) -> CommaSeparated ws a -> b
+ Waargonaut.Encode.Builder.JArray: jArrayBuilder :: Monoid b => Builder t b -> (Builder t b -> ws -> b) -> ((Builder t b -> ws -> b) -> Builder t b -> a -> b) -> JArray ws a -> b
+ Waargonaut.Encode.Builder.JChar: jCharBuilder :: (Monoid b, HeXaDeCiMaL digit) => Builder t b -> JChar digit -> b
+ Waargonaut.Encode.Builder.JNumber: jNumberBuilder :: Monoid b => Builder t b -> JNumber -> b
+ Waargonaut.Encode.Builder.JObject: jObjectBuilder :: Monoid b => Builder t b -> (Builder t b -> ws -> b) -> ((Builder t b -> ws -> b) -> Builder t b -> a -> b) -> JObject ws a -> b
+ Waargonaut.Encode.Builder.JString: jStringBuilder :: Monoid b => Builder t b -> JString -> b
+ Waargonaut.Encode.Builder.Types: Builder :: Char -> b -> t -> b -> Int -> b -> Builder t b
+ Waargonaut.Encode.Builder.Types: [fromChar] :: Builder t b -> Char -> b
+ Waargonaut.Encode.Builder.Types: [fromChunk] :: Builder t b -> t -> b
+ Waargonaut.Encode.Builder.Types: [fromInt] :: Builder t b -> Int -> b
+ Waargonaut.Encode.Builder.Types: data Builder t b
+ Waargonaut.Encode.Builder.Whitespace: whitespaceBuilder :: Monoid b => Builder t b -> Whitespace -> b
+ Waargonaut.Encode.Builder.Whitespace: wsBuilder :: Monoid b => Builder t b -> WS -> b
+ Waargonaut.Encode.Builder.Whitespace: wsRemover :: Monoid b => Builder t b -> WS -> b
+ Waargonaut.Lens: _ArrayOf :: Prism' Json x -> Prism' Json (Vector x)
+ Waargonaut.Lens: _Bool :: Prism' Json Bool
+ Waargonaut.Lens: _Null :: Prism' Json ()
+ Waargonaut.Lens: _Number :: Prism' Json Scientific
+ Waargonaut.Lens: _ObjHashMapOf :: Prism' Json x -> Prism' Json (HashMap Text x)
+ Waargonaut.Lens: _String :: Prism' Json Text
+ Waargonaut.Lens: _TextJson :: (CharParsing g, Monad g, Show e) => (forall a. g a -> Text -> Either e a) -> Prism' Text Json
+ Waargonaut.Types.CommaSep: fromCommaSep :: Traversal' j (CommaSeparated ws x) -> v -> (Elems ws a -> v) -> (x -> Maybe a) -> j -> Either j v
+ Waargonaut.Types.CommaSep.Elem: Comma :: Comma
+ Waargonaut.Types.CommaSep.Elem: Elem :: a -> f (Comma, ws) -> Elem f ws a
+ Waargonaut.Types.CommaSep.Elem: [_elemTrailing] :: Elem f ws a -> f (Comma, ws)
+ Waargonaut.Types.CommaSep.Elem: [_elemVal] :: Elem f ws a -> a
+ Waargonaut.Types.CommaSep.Elem: _ElemTrailingIso :: (Monoid ws, Monoid ws') => Iso (Elem Identity ws a) (Elem Identity ws' a') (Elem Maybe ws a) (Elem Maybe ws' a')
+ Waargonaut.Types.CommaSep.Elem: class HasElem c f ws a | c -> f ws a
+ Waargonaut.Types.CommaSep.Elem: data Comma
+ Waargonaut.Types.CommaSep.Elem: data Elem f ws a
+ Waargonaut.Types.CommaSep.Elem: elem :: HasElem c f ws a => Lens' c (Elem f ws a)
+ Waargonaut.Types.CommaSep.Elem: elemTrailing :: HasElem c f ws a => Lens' c (f (Comma, ws))
+ Waargonaut.Types.CommaSep.Elem: elemVal :: HasElem c f ws a => Lens' c a
+ Waargonaut.Types.CommaSep.Elem: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.CommaSep.Elem.Elem f ws a)
+ Waargonaut.Types.CommaSep.Elem: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.CommaSep.Elem.Elem f ws a)
+ Waargonaut.Types.CommaSep.Elem: instance (GHC.Base.Monoid ws, GHC.Base.Applicative f) => GHC.Base.Applicative (Waargonaut.Types.CommaSep.Elem.Elem f ws)
+ Waargonaut.Types.CommaSep.Elem: instance Data.Foldable.Foldable (Waargonaut.Types.CommaSep.Elem.Elem f ws)
+ Waargonaut.Types.CommaSep.Elem: instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Waargonaut.Types.CommaSep.Elem.Elem f)
+ Waargonaut.Types.CommaSep.Elem: instance Data.Traversable.Traversable (Waargonaut.Types.CommaSep.Elem.Elem f ws)
+ Waargonaut.Types.CommaSep.Elem: instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Waargonaut.Types.CommaSep.Elem.Elem f)
+ Waargonaut.Types.CommaSep.Elem: instance GHC.Base.Functor (Waargonaut.Types.CommaSep.Elem.Elem f ws)
+ Waargonaut.Types.CommaSep.Elem: instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Waargonaut.Types.CommaSep.Elem.Elem f)
+ Waargonaut.Types.CommaSep.Elem: instance GHC.Classes.Eq Waargonaut.Types.CommaSep.Elem.Comma
+ Waargonaut.Types.CommaSep.Elem: instance GHC.Show.Show Waargonaut.Types.CommaSep.Elem.Comma
+ Waargonaut.Types.CommaSep.Elem: instance Waargonaut.Types.CommaSep.Elem.HasElem (Waargonaut.Types.CommaSep.Elem.Elem f ws a) f ws a
+ Waargonaut.Types.CommaSep.Elem: parseComma :: CharParsing f => f Comma
+ Waargonaut.Types.CommaSep.Elem: parseCommaTrailingMaybe :: CharParsing f => f ws -> f (Maybe (Comma, ws))
+ Waargonaut.Types.CommaSep.Elems: Elems :: Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
+ Waargonaut.Types.CommaSep.Elems: [_elemsElems] :: Elems ws a -> Vector (Elem Identity ws a)
+ Waargonaut.Types.CommaSep.Elems: [_elemsLast] :: Elems ws a -> Elem Maybe ws a
+ Waargonaut.Types.CommaSep.Elems: class HasElems c ws a | c -> ws a
+ Waargonaut.Types.CommaSep.Elems: consElems :: Monoid ws => ((Comma, ws), a) -> Elems ws a -> Elems ws a
+ Waargonaut.Types.CommaSep.Elems: data Elems ws a
+ Waargonaut.Types.CommaSep.Elems: elems :: HasElems c ws a => Lens' c (Elems ws a)
+ Waargonaut.Types.CommaSep.Elems: elemsElems :: HasElems c ws a => Lens' c (Vector (Elem Identity ws a))
+ Waargonaut.Types.CommaSep.Elems: elemsLast :: HasElems c ws a => Lens' c (Elem Maybe ws a)
+ Waargonaut.Types.CommaSep.Elems: instance (GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.CommaSep.Elems.Elems ws a)
+ Waargonaut.Types.CommaSep.Elems: instance (GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.CommaSep.Elems.Elems ws a)
+ Waargonaut.Types.CommaSep.Elems: instance Data.Bifoldable.Bifoldable Waargonaut.Types.CommaSep.Elems.Elems
+ Waargonaut.Types.CommaSep.Elems: instance Data.Bifunctor.Bifunctor Waargonaut.Types.CommaSep.Elems.Elems
+ Waargonaut.Types.CommaSep.Elems: instance Data.Bitraversable.Bitraversable Waargonaut.Types.CommaSep.Elems.Elems
+ Waargonaut.Types.CommaSep.Elems: instance Data.Foldable.Foldable (Waargonaut.Types.CommaSep.Elems.Elems ws)
+ Waargonaut.Types.CommaSep.Elems: instance Data.Traversable.Traversable (Waargonaut.Types.CommaSep.Elems.Elems ws)
+ Waargonaut.Types.CommaSep.Elems: instance GHC.Base.Functor (Waargonaut.Types.CommaSep.Elems.Elems ws)
+ Waargonaut.Types.CommaSep.Elems: instance GHC.Base.Monoid ws => GHC.Base.Applicative (Waargonaut.Types.CommaSep.Elems.Elems ws)
+ Waargonaut.Types.CommaSep.Elems: instance GHC.Base.Monoid ws => GHC.Base.Semigroup (Waargonaut.Types.CommaSep.Elems.Elems ws a)
+ Waargonaut.Types.CommaSep.Elems: instance Waargonaut.Types.CommaSep.Elems.HasElems (Waargonaut.Types.CommaSep.Elems.Elems ws a) ws a
+ Waargonaut.Types.CommaSep.Elems: parseCommaSeparatedElems :: (Monad f, CharParsing f) => f ws -> f a -> f (Elems ws a)
+ Waargonaut.Types.CommaSep.Elems: unconsElems :: Monoid ws => Elems ws a -> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
+ Waargonaut.Types.JChar: charToJChar :: Char -> Maybe (JChar HeXDigit)
+ Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.Escaped.AsEscaped (Waargonaut.Types.JChar.JChar digit) digit
+ Waargonaut.Types.JChar: instance Waargonaut.Types.JChar.Unescaped.AsUnescaped (Waargonaut.Types.JChar.JChar digit)
+ Waargonaut.Types.JChar.Escaped: Backspace :: Escaped digit
+ Waargonaut.Types.JChar.Escaped: Hex :: (HexDigit4 digit) -> Escaped digit
+ Waargonaut.Types.JChar.Escaped: QuotationMark :: Escaped digit
+ Waargonaut.Types.JChar.Escaped: ReverseSolidus :: Escaped digit
+ Waargonaut.Types.JChar.Escaped: Solidus :: Escaped digit
+ Waargonaut.Types.JChar.Escaped: WhiteSpace :: Whitespace -> Escaped digit
+ Waargonaut.Types.JChar.Escaped: _Backspace :: AsEscaped r digit => Prism' r ()
+ Waargonaut.Types.JChar.Escaped: _Escaped :: AsEscaped r digit => Prism' r (Escaped digit)
+ Waargonaut.Types.JChar.Escaped: _Hex :: AsEscaped r digit => Prism' r (HexDigit4 digit)
+ Waargonaut.Types.JChar.Escaped: _QuotationMark :: AsEscaped r digit => Prism' r ()
+ Waargonaut.Types.JChar.Escaped: _ReverseSolidus :: AsEscaped r digit => Prism' r ()
+ Waargonaut.Types.JChar.Escaped: _Solidus :: AsEscaped r digit => Prism' r ()
+ Waargonaut.Types.JChar.Escaped: _WhiteSpace :: AsEscaped r digit => Prism' r Whitespace
+ Waargonaut.Types.JChar.Escaped: charToEscaped :: Char -> Maybe (Escaped HeXDigit)
+ Waargonaut.Types.JChar.Escaped: class AsEscaped r digit | r -> digit
+ Waargonaut.Types.JChar.Escaped: data Escaped digit
+ Waargonaut.Types.JChar.Escaped: escapedToChar :: Escaped HeXDigit -> Char
+ Waargonaut.Types.JChar.Escaped: instance Data.Foldable.Foldable Waargonaut.Types.JChar.Escaped.Escaped
+ Waargonaut.Types.JChar.Escaped: instance Data.Traversable.Traversable Waargonaut.Types.JChar.Escaped.Escaped
+ Waargonaut.Types.JChar.Escaped: instance GHC.Base.Functor Waargonaut.Types.JChar.Escaped.Escaped
+ Waargonaut.Types.JChar.Escaped: instance GHC.Classes.Eq digit => GHC.Classes.Eq (Waargonaut.Types.JChar.Escaped.Escaped digit)
+ Waargonaut.Types.JChar.Escaped: instance GHC.Classes.Ord digit => GHC.Classes.Ord (Waargonaut.Types.JChar.Escaped.Escaped digit)
+ Waargonaut.Types.JChar.Escaped: instance GHC.Show.Show digit => GHC.Show.Show (Waargonaut.Types.JChar.Escaped.Escaped digit)
+ Waargonaut.Types.JChar.Escaped: instance Waargonaut.Types.JChar.Escaped.AsEscaped (Waargonaut.Types.JChar.Escaped.Escaped digit) digit
+ Waargonaut.Types.JChar.Escaped: parseEscaped :: (CharParsing f, HeXaDeCiMaL digit) => f (Escaped digit)
+ Waargonaut.Types.JChar.HexDigit4: HexDigit4 :: d -> d -> d -> d -> HexDigit4 d
+ Waargonaut.Types.JChar.HexDigit4: charToHexDigit4 :: Char -> Maybe (HexDigit4 HeXDigit)
+ Waargonaut.Types.JChar.HexDigit4: class HasHexDigit4 c d | c -> d
+ Waargonaut.Types.JChar.HexDigit4: data HexDigit4 d
+ Waargonaut.Types.JChar.HexDigit4: hexDigit4 :: HasHexDigit4 c d => Lens' c (HexDigit4 d)
+ Waargonaut.Types.JChar.HexDigit4: hexDigit4ToChar :: HexDigit4 HeXDigit -> Char
+ Waargonaut.Types.JChar.HexDigit4: instance Data.Foldable.Foldable Waargonaut.Types.JChar.HexDigit4.HexDigit4
+ Waargonaut.Types.JChar.HexDigit4: instance Data.Traversable.Traversable Waargonaut.Types.JChar.HexDigit4.HexDigit4
+ Waargonaut.Types.JChar.HexDigit4: instance GHC.Base.Functor Waargonaut.Types.JChar.HexDigit4.HexDigit4
+ Waargonaut.Types.JChar.HexDigit4: instance GHC.Classes.Eq d => GHC.Classes.Eq (Waargonaut.Types.JChar.HexDigit4.HexDigit4 d)
+ Waargonaut.Types.JChar.HexDigit4: instance GHC.Classes.Ord d => GHC.Classes.Ord (Waargonaut.Types.JChar.HexDigit4.HexDigit4 d)
+ Waargonaut.Types.JChar.HexDigit4: instance GHC.Show.Show d => GHC.Show.Show (Waargonaut.Types.JChar.HexDigit4.HexDigit4 d)
+ Waargonaut.Types.JChar.HexDigit4: instance Waargonaut.Types.JChar.HexDigit4.HasHexDigit4 (Waargonaut.Types.JChar.HexDigit4.HexDigit4 d) d
+ Waargonaut.Types.JChar.HexDigit4: parseHexDigit4 :: (CharParsing f, HeXaDeCiMaL digit) => f (HexDigit4 digit)
+ Waargonaut.Types.JChar.Unescaped: Unescaped :: Char -> Unescaped
+ Waargonaut.Types.JChar.Unescaped: _Unescaped :: AsUnescaped a => Prism' a Unescaped
+ Waargonaut.Types.JChar.Unescaped: class AsUnescaped a
+ Waargonaut.Types.JChar.Unescaped: instance GHC.Classes.Eq Waargonaut.Types.JChar.Unescaped.Unescaped
+ Waargonaut.Types.JChar.Unescaped: instance GHC.Classes.Ord Waargonaut.Types.JChar.Unescaped.Unescaped
+ Waargonaut.Types.JChar.Unescaped: instance GHC.Show.Show Waargonaut.Types.JChar.Unescaped.Unescaped
+ Waargonaut.Types.JChar.Unescaped: instance Waargonaut.Types.JChar.Unescaped.AsUnescaped GHC.Types.Char
+ Waargonaut.Types.JChar.Unescaped: instance Waargonaut.Types.JChar.Unescaped.AsUnescaped Waargonaut.Types.JChar.Unescaped.Unescaped
+ Waargonaut.Types.JChar.Unescaped: newtype Unescaped
+ Waargonaut.Types.JChar.Unescaped: parseUnescaped :: CharParsing f => f Unescaped
+ Waargonaut.Types.JNumber: jIntToDigits :: JInt -> NonEmpty DecDigit
+ Waargonaut.Types.JObject.JAssoc: JAssoc :: JString -> ws -> ws -> a -> JAssoc ws a
+ Waargonaut.Types.JObject.JAssoc: [_jsonAssocKeyTrailingWS] :: JAssoc ws a -> ws
+ Waargonaut.Types.JObject.JAssoc: [_jsonAssocKey] :: JAssoc ws a -> JString
+ Waargonaut.Types.JObject.JAssoc: [_jsonAssocValPreceedingWS] :: JAssoc ws a -> ws
+ Waargonaut.Types.JObject.JAssoc: [_jsonAssocVal] :: JAssoc ws a -> a
+ Waargonaut.Types.JObject.JAssoc: class HasJAssoc c ws a | c -> ws a
+ Waargonaut.Types.JObject.JAssoc: data JAssoc ws a
+ Waargonaut.Types.JObject.JAssoc: instance (GHC.Classes.Eq ws, GHC.Classes.Eq a) => GHC.Classes.Eq (Waargonaut.Types.JObject.JAssoc.JAssoc ws a)
+ Waargonaut.Types.JObject.JAssoc: instance (GHC.Show.Show ws, GHC.Show.Show a) => GHC.Show.Show (Waargonaut.Types.JObject.JAssoc.JAssoc ws a)
+ Waargonaut.Types.JObject.JAssoc: instance Data.Bifoldable.Bifoldable Waargonaut.Types.JObject.JAssoc.JAssoc
+ Waargonaut.Types.JObject.JAssoc: instance Data.Bifunctor.Bifunctor Waargonaut.Types.JObject.JAssoc.JAssoc
+ Waargonaut.Types.JObject.JAssoc: instance Data.Bitraversable.Bitraversable Waargonaut.Types.JObject.JAssoc.JAssoc
+ Waargonaut.Types.JObject.JAssoc: instance Data.Foldable.Foldable (Waargonaut.Types.JObject.JAssoc.JAssoc ws)
+ Waargonaut.Types.JObject.JAssoc: instance Data.Traversable.Traversable (Waargonaut.Types.JObject.JAssoc.JAssoc ws)
+ Waargonaut.Types.JObject.JAssoc: instance GHC.Base.Functor (Waargonaut.Types.JObject.JAssoc.JAssoc ws)
+ Waargonaut.Types.JObject.JAssoc: instance Waargonaut.Types.JObject.JAssoc.HasJAssoc (Waargonaut.Types.JObject.JAssoc.JAssoc ws a) ws a
+ Waargonaut.Types.JObject.JAssoc: jAssoc :: HasJAssoc c ws a => Lens' c (JAssoc ws a)
+ Waargonaut.Types.JObject.JAssoc: jAssocAlterF :: (Monoid ws, Functor f) => Text -> (Maybe a -> f (Maybe a)) -> Maybe (JAssoc ws a) -> f (Maybe (JAssoc ws a))
+ Waargonaut.Types.JObject.JAssoc: jsonAssocKey :: HasJAssoc c ws a => Lens' c JString
+ Waargonaut.Types.JObject.JAssoc: jsonAssocKeyTrailingWS :: HasJAssoc c ws a => Lens' c ws
+ Waargonaut.Types.JObject.JAssoc: jsonAssocVal :: HasJAssoc c ws a => Lens' c a
+ Waargonaut.Types.JObject.JAssoc: jsonAssocValPreceedingWS :: HasJAssoc c ws a => Lens' c ws
+ Waargonaut.Types.JObject.JAssoc: parseJAssoc :: (Monad f, CharParsing f) => f ws -> f a -> f (JAssoc ws a)
- Waargonaut: waargonautBuilder :: (WS -> Builder) -> Json -> Builder
+ Waargonaut: waargonautBuilder :: (IsString t, Monoid b) => (Builder t b -> WS -> b) -> Builder t b -> Json -> b
- Waargonaut.Test: roundTripSimple :: (Eq b, Monad f, CharParsing f, Monad g, Show e) => (f Json -> ByteString -> Either e Json) -> Encoder g b -> Decoder g b -> b -> g (Either (DecodeError, CursorHistory) Bool)
+ Waargonaut.Test: roundTripSimple :: (Eq b, Monad f, CharParsing f, Monad g, Show e) => (forall a. f a -> Text -> Either e a) -> Encoder g b -> Decoder g b -> b -> g (Either (DecodeError, CursorHistory) Bool)
- Waargonaut.Types.JChar: EscapedJChar :: (JCharEscaped digit) -> JChar digit
+ Waargonaut.Types.JChar: EscapedJChar :: (Escaped digit) -> JChar digit
- Waargonaut.Types.JChar: UnescapedJChar :: JCharUnescaped -> JChar digit
+ Waargonaut.Types.JChar: UnescapedJChar :: Unescaped -> JChar digit
- Waargonaut.Types.JChar: _EscapedJChar :: AsJChar r digit => Prism' r (JCharEscaped digit)
+ Waargonaut.Types.JChar: _EscapedJChar :: AsJChar r digit => Prism' r (Escaped digit)
- Waargonaut.Types.JChar: _UnescapedJChar :: AsJChar r digit => Prism' r JCharUnescaped
+ Waargonaut.Types.JChar: _UnescapedJChar :: AsJChar r digit => Prism' r Unescaped
- Waargonaut.Types.JChar: jCharToChar :: HeXaDeCiMaL digit => JChar digit -> Char
+ Waargonaut.Types.JChar: jCharToChar :: JChar HeXDigit -> Char
- Waargonaut.Types.JString: _JStringText :: Prism' JString Text
+ Waargonaut.Types.JString: _JStringText :: (Profunctor p, Applicative f) => p Text (f Text) -> p JString (f JString)
Files
- changelog.md +43/−0
- src/Waargonaut.hs +56/−28
- src/Waargonaut/Attoparsec.hs +65/−0
- src/Waargonaut/Decode.hs +18/−131
- src/Waargonaut/Decode/Internal.hs +42/−41
- src/Waargonaut/Decode/Runners.hs +267/−0
- src/Waargonaut/Decode/Traversal.hs +2/−2
- src/Waargonaut/Decode/Types.hs +11/−3
- src/Waargonaut/Encode.hs +132/−24
- src/Waargonaut/Encode/Builder.hs +66/−0
- src/Waargonaut/Encode/Builder/CommaSep.hs +45/−0
- src/Waargonaut/Encode/Builder/JArray.hs +17/−0
- src/Waargonaut/Encode/Builder/JChar.hs +34/−0
- src/Waargonaut/Encode/Builder/JNumber.hs +85/−0
- src/Waargonaut/Encode/Builder/JObject.hs +31/−0
- src/Waargonaut/Encode/Builder/JString.hs +50/−0
- src/Waargonaut/Encode/Builder/Types.hs +7/−0
- src/Waargonaut/Encode/Builder/Whitespace.hs +29/−0
- src/Waargonaut/Generic.hs +21/−14
- src/Waargonaut/Lens.hs +117/−0
- src/Waargonaut/Prettier.hs +33/−29
- src/Waargonaut/Test.hs +6/−10
- src/Waargonaut/Types/CommaSep.hs +77/−279
- src/Waargonaut/Types/CommaSep/Elem.hs +137/−0
- src/Waargonaut/Types/CommaSep/Elems.hs +166/−0
- src/Waargonaut/Types/JArray.hs +1/−14
- src/Waargonaut/Types/JChar.hs +61/−370
- src/Waargonaut/Types/JChar/Escaped.hs +198/−0
- src/Waargonaut/Types/JChar/HexDigit4.hs +136/−0
- src/Waargonaut/Types/JChar/Unescaped.hs +86/−0
- src/Waargonaut/Types/JNumber.hs +40/−101
- src/Waargonaut/Types/JObject.hs +34/−119
- src/Waargonaut/Types/JObject/JAssoc.hs +119/−0
- src/Waargonaut/Types/JString.hs +33/−68
- src/Waargonaut/Types/Json.hs +22/−49
- src/Waargonaut/Types/Whitespace.hs +0/−24
- test/Decoder.hs +106/−31
- test/Decoder/Laws.hs +2/−3
- test/Encoder.hs +1/−1
- test/Encoder/Laws.hs +1/−1
- test/Golden.hs +37/−0
- test/Json.hs +89/−11
- test/Main.hs +46/−303
- test/Properties.hs +281/−0
- test/Types/Common.hs +27/−46
- test/Types/JChar.hs +14/−18
- test/json-data/bad-json/no_comma_arr.json +1/−0
- test/json-data/bad-json/no_comma_obj.json +1/−0
- test/json-data/goldens/backslash128.json.golden +1/−0
- test/json-data/goldens/empty_arr_empty_ws.json.golden +1/−0
- test/json-data/goldens/image_obj.json.golden +14/−0
- test/json-data/goldens/location_array.json.golden +22/−0
- test/json-data/goldens/nested_arrs.json.golden +1/−0
- test/json-data/goldens/null_arr_trailing_comma_ws.json.golden +1/−0
- test/json-data/goldens/numbers.json.golden +1/−0
- test/json-data/goldens/twitter100.json.golden +1/−0
- test/json-data/goldens/twitter_with_hex_vals.json.golden +1/−0
- test/json-data/goldens/unicode_2705.json.golden +1/−0
- test/json-data/image_obj.json +14/−0
- test/json-data/test1.json +0/−14
- test/json-data/test2.json +0/−22
- test/json-data/test3.json +0/−1
- test/json-data/test4.json +0/−1
- test/json-data/test5.json +0/−1
- test/json-data/test6.json +0/−1
- test/json-data/test7.json +0/−1
- test/json-data/twitter_with_hex_vals.json +1/−0
- test/json-data/unicode_2705.json +1/−0
- waargonaut.cabal +87/−41
changelog.md view
@@ -1,5 +1,48 @@ # Revision history for waargonaut +## 0.6.0.0 -- 2019-02-19++#### Fixes++* Handling of HeXDigit4 values was not correct. The bug was partly due to the+ choice of optic, instead of producing a (type/failure) error when working with+ mixed-case hex values, it seems to be zero'ing them out.+* Added regression tests++#### Rework++* Redesigned ParseFn to handle:+ * Data.String.String+ * Data.Text.Text+ * Data.ByteString.ByteString+* Updated documentation for ParseFn to match changes+* Updated documentation for default parsing functions+* Generalised the Builder process to handle Text and ByteString+ * Created a record type to hold the required functions for builders+ * Created submodules to house the generalised builders (see Waargonaut.Encode.Builder and friends)+ * Added test to ensure both builders produce identical output+* Updated documentation for Encode process to match changes+* Added deprecation notice to `Waargonaut.Decode.Traversal`++#### Cleanup++* Factored out components into more submodules:+ * UnescapedJChar+ * EscapedJChar+ * HexDigit4+ * Elem+ * Elems+ * JAssoc+ * Decode.Runners+* Updated documentation if required for module changes.+* Deleted commented out code+* Changed all file textual encoding/decoding tests to Test.Tasty.Golden.++#### New hotness++* Added a few prisms to allow for similar behaviour to the lens-aeson package.+* Added property tests for these new prisms to check they comply with the prism law.+ ## 0.5.2.1 -- 2019-01-08 * Upgraded the nix overrides to use the overlay technique.
src/Waargonaut.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-} -- | Welcome to Waargonaut, we hope you enjoy your stay. -- -- The handling of JSON is managed using the 'Waargonaut.Decode.Decoder' and@@ -15,15 +13,21 @@ -- * Simple Encode -- $basicencode + -- * Types Json (..) , JType (..)++ -- * Parser / Builder , parseWaargonaut , waargonautBuilder+ ) where -import Waargonaut.Types.Json (JType (..), Json (..), parseWaargonaut,- waargonautBuilder)+import Waargonaut.Types.Json (JType (..), Json (..),+ parseWaargonaut) +import Waargonaut.Encode.Builder (waargonautBuilder)+ -- $basicdecode -- -- We will work through a basic example, using the following type:@@ -141,46 +145,62 @@ -- allows you to choose your own favourite parsing library to do the heavy lifting. Provided it -- implements the right typeclasses from 'parsers'. ----- To apply a 'Waargonaut.Decode.Decoder' to some output you will need:+-- To apply a 'Waargonaut.Decode.Decoder' to some input you will need one of the+-- decoder running functions from 'Waargonaut.Decode'. There are a few different+-- functions provided for some of the common input text-like types.: -- -- @--- runDecode--- :: Monad f--- => Decoder f a--- -> ParseFn--- -> JCurs--- -> f (Either (DecodeError, CursorHistory) a)+-- decodeFromByteString+-- :: ( CharParsing f+-- , Monad f+-- , Monad g+-- , Show e+-- )+-- => (forall a. f a -> ByteString -> Either e a)+-- -> Decoder g x+-- -> ByteString+-- -> g (Either (DecodeError, CursorHistory) x) -- @ --+--+-- As well as a parsing function from your parsing library of choice, that also+-- has an implementation of the 'CharParsing' typeclass from 'parsers'. We will+-- use 'attoparsec' in the examples below.+-- -- @--- runDecode personDecode parseByteString (mkCursor inp)+-- import qualified Data.Attoparsec.ByteString as AB -- @ ----- Which will run the 'personDecode' 'Waargonaut.Decode.Decoder' using the parsing function--- ('parseByteString'), starting at the cursor from the top of the 'inp' input.+-- @+-- decodeFromByteString AB.parseOnly personDecode inp+-- @ ----- We use the 'Waargonaut.Decode.mkCursor' function to create the index for our, presumed to be--- JSON containing, 'Data.ByteString.ByteString' input.+-- Which will run the 'personDecode' 'Waargonaut.Decode.Decoder' using the parsing function+-- (@AB.parseOnly@), starting at the cursor from the top of the 'inp' input. -- -- Again the 'Monad' constraint is there so that you have more options available for utilising the -- 'Waargonaut.Decode.Decoder' in ways we haven't thought of. ----- Or if you don't need the 'Monad' constraint and you don't need to call--- 'Waargonaut.Decode.mkCursor' separately, then you may use 'Waargonaut.Decode.simpleDecode'. This--- function specialises the 'Monad' constraint to 'Data.Functor.Identity'.:+-- Or if you don't need the 'Monad' constraint then you may use 'Waargonaut.Decode.pureDecodeFromByteString'.+-- This function specialises the 'Monad' constraint to 'Data.Functor.Identity'.: -- -- @--- simpleDecode--- :: Decoder Identity a--- -> ParseFn+-- pureDecodeFromByteString+-- :: ( Monad f+-- , CharParsing f+-- , Show e+-- )+-- => (forall a. f a -> ByteString -> Either e a)+-- -> Decoder Identity x -- -> ByteString--- -> Either (DecodeError, CursorHistory) a+-- -> Either (DecodeError, CursorHistory) x -- @ -- -- @--- simpleDecode personDecode parseByteString inp+-- pureDecodeFromByteString AB.parseOnly personDecode inp -- @ --+-- Waargonaut provides some default implementations using the <https://hackage.haskell.org/package/attoparsec attoparsec> package in the 'Waargonaut.Attoparsec' module. These functions have exactly the same behaviour as the functions above, without the need to provide the parsing function. -- $basicencode --@@ -241,22 +261,30 @@ -- To then turn these values into JSON output: -- -- @--- simpleEncodeNoSpaces :: Applicative f => Encoder f a -> a -> f ByteString+-- simpleEncodeText :: Applicative f => Encoder f a -> a -> f Text+-- simpleEncodeTextNoSpaces :: Applicative f => Encoder f a -> a -> f Text+--+-- simpleEncodeByteString :: Applicative f => Encoder f a -> a -> f ByteString+-- simpleEncodeByteStringNoSpaces :: Applicative f => Encoder f a -> a -> f ByteString -- @ -- -- Or -- -- @--- simplePureEncodeNoSpaces :: Encoder' a -> a -> ByteString+-- simplePureEncodeText :: Encoder' a -> a -> Text+-- simplePureEncodeTextNoSpaces :: Encoder' a -> a -> Text+--+-- simplePureEncodeByteString :: Encoder' a -> a -> ByteString+-- simplePureEncodeByteStringNoSpaces :: Encoder' a -> a -> ByteString -- @ ----- The latter specialises the 'f' to be 'Data.Functor.Identity'.+-- The latter functions specialise the 'f' to be 'Data.Functor.Identity'. -- -- Then, like the use of the 'Waargonaut.Decode.Decoder' you select the 'Waargonaut.Encode.Encoder' -- you wish to use and run it against a value of a matching type: -- -- @--- simplePureEncodeNoSpaces personEncoder (Person \"Krag\" 33 \"Red House 4, Three Neck Lane, Greentown.\" [86,3,32,42,73])+-- simplePureEncodeTextNoSpaces personEncoder (Person \"Krag\" 33 \"Red House 4, Three Neck Lane, Greentown.\" [86,3,32,42,73]) -- = -- "{\"name\":\"Krag\",\"age\":88,\"address\":\"Red House 4, Three Neck Lane, Greentown.\",\"numbers\":[86,3,32,42,73]}" -- @
+ src/Waargonaut/Attoparsec.hs view
@@ -0,0 +1,65 @@+-- | Some default decoder implementations using the @attoparsec@ package.+--+-- Waargonaut works with any parser that has an instance of the+-- 'Text.Parser.Char.CharParsing' typeclass. So you're able to select from a few+-- different parsing libraries, depending on your needs. This module provides+-- some convenient defaults using the <https://hackage.haskell.org/package/attoparsec attoparsec> package.+--+-- These functions are implemented using the 'decodeFromX' functions in the+-- 'Waargonaut.Decode' module. They use the @parseOnly@ function, from either+-- the @Text@ or @ByteString@ attoparsec modules.+--+module Waargonaut.Attoparsec+ ( -- * Decoders+ decodeAttoparsecText+ , decodeAttoparsecByteString+ , pureDecodeAttoparsecText+ , pureDecodeAttoparsecByteString+ ) where++import Data.Functor.Identity (Identity)++import Data.ByteString (ByteString)+import Data.Text (Text)++import qualified Data.Attoparsec.ByteString as AB+import qualified Data.Attoparsec.Text as AT++import Waargonaut.Decode (CursorHistory, Decoder)+import Waargonaut.Decode.Error (DecodeError)++import qualified Waargonaut.Decode as D++-- | Use the 'AT.parseOnly' function as our default parser for decoding 'Text' input.+decodeAttoparsecText+ :: Monad f+ => Decoder f a+ -> Text+ -> f (Either (DecodeError, CursorHistory) a)+decodeAttoparsecText decoder =+ D.decodeFromText AT.parseOnly decoder++-- | Use the 'AB.parseOnly' function as our default parser for decoding 'ByteString' input.+decodeAttoparsecByteString+ :: Monad f+ => Decoder f a+ -> ByteString+ -> f (Either (DecodeError, CursorHistory) a)+decodeAttoparsecByteString decoder =+ D.decodeFromByteString AB.parseOnly decoder++-- | As per 'decodeAttoparsecText' but with @f@ specialised to 'Identity'.+pureDecodeAttoparsecText+ :: Decoder Identity a+ -> Text+ -> Either (DecodeError, CursorHistory) a+pureDecodeAttoparsecText decoder =+ D.pureDecodeFromText AT.parseOnly decoder++-- | As per 'decodeAttoparsecByteString' but with @f@ specialised to 'Identity'.+pureDecodeAttoparsecByteString+ :: Decoder Identity a+ -> ByteString+ -> Either (DecodeError, CursorHistory) a+pureDecodeAttoparsecByteString decoder =+ D.pureDecodeFromByteString AB.parseOnly decoder
src/Waargonaut/Decode.hs view
@@ -18,21 +18,15 @@ , DecodeResult (..) , Decoder (..) , JCurs (..)- , ParseFn , Err (..) , JsonType (..) -- * Runners- , runDecode- , runDecodeResult- , runPureDecode- , simpleDecode- , overrideParser- , generaliseDecoder+ , module Waargonaut.Decode.Runners -- * Helpers+ , generaliseDecoder , DI.ppCursorHistory- , parseWith -- * Cursors , withCursor@@ -70,6 +64,7 @@ , rank , prismD , prismDOrFail+ , prismDOrFail' , json , int , scientific@@ -100,17 +95,17 @@ import Control.Lens (Cons, Lens', Prism', Snoc, cons, lens, matching, modifying,- over, preview, snoc,+ preview, snoc, traverseOf, view, ( # ), (.~), (^.),- _Left, _Wrapped)+ _Wrapped) import Control.Monad.Error.Lens (throwing) import Prelude (Bool, Bounded, Char, Eq, Int, Integral,- Show, String,- fromIntegral, show,- (-), (==))+ String,+ fromIntegral, (-),+ (==)) import Control.Applicative (Applicative (..)) import Control.Category ((.))@@ -121,23 +116,21 @@ import Control.Monad.Except (catchError, lift, liftEither) import Control.Monad.Reader (ReaderT (..), ask,- local, runReaderT)+ runReaderT) import Control.Monad.State (MonadState) import Control.Error.Util (note) import Control.Monad.Error.Hoist ((<!?>), (<?>)) -import Data.Bool (Bool (..)) import Data.Either (Either (..)) import qualified Data.Either as Either (either)-import Data.Foldable (Foldable, foldl,- foldr)+import Data.Foldable (Foldable, elem,+ foldl, foldr) import Data.Function (const, flip, ($), (&)) import Data.Functor (fmap, (<$), (<$>)) import Data.Functor.Alt ((<!>))-import Data.Functor.Identity (Identity,- runIdentity)+import Data.Functor.Identity (Identity) import Data.Monoid (mempty) import Data.Scientific (Scientific) @@ -148,10 +141,7 @@ successor', zero') import Data.Text (Text)-import qualified Data.Text as Text -import Text.Parser.Char (CharParsing)- import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS8 import qualified Data.ByteString.Lazy as BL@@ -162,7 +152,6 @@ import qualified HaskellWorks.Data.BalancedParens.FindOpen as BP import HaskellWorks.Data.Bits ((.?.))-import HaskellWorks.Data.FromByteString (fromByteString) import HaskellWorks.Data.TreeCursor (TreeCursor (..)) import HaskellWorks.Data.Json.Cursor (JsonCursor (..))@@ -172,18 +161,20 @@ DecodeError (..), Err (..)) import Waargonaut.Decode.ZipperMove (ZipperMove (..))-import Waargonaut.Types+import Waargonaut.Types (Json) import qualified Waargonaut.Decode.Internal as DI +import Waargonaut.Decode.Runners+ import Waargonaut.Decode.Types (CursorHistory, DecodeResult (..), Decoder (..), JCurs (..), JsonType (..),- ParseFn, SuccinctCursor,- jsonTypeAt)+ jsonTypeAt,+ mkCursor) -- | Function to define a 'Decoder' for a specific data type. --@@ -224,11 +215,6 @@ withCursor g = Decoder $ \p -> DI.runDecoder' $ DI.withCursor' (flip runReaderT p . unDecodeResult . g) --- | Take a 'ByteString' input and build an index of the JSON structure inside----mkCursor :: ByteString -> JCurs-mkCursor = JCurs . fromByteString- -- | Lens for accessing the 'rank' of the 'JsonCursor'. The 'rank' forms part of -- the calculation that is the cursors current position in the index. --@@ -582,7 +568,7 @@ -> JCurs -> DecodeResult f a withType t d c =- if maybe False (== t) $ jsonTypeAt (unJCurs c) then d c+ if elem t $ jsonTypeAt (unJCurs c) then d c else throwing _TypeMismatch t -- | Higher order function for combining a folding function with repeated cursor@@ -682,105 +668,6 @@ -> DecodeResult f s rightwardSnoc = foldCursor snoc moveRight1---- | Run a 'Decoder' for the final result to see if you have your 'a' or an error.-runDecode- :: Monad f- => Decoder f a- -> ParseFn- -> JCurs- -> f (Either (DecodeError, CursorHistory) a)-runDecode dr p =- DI.runDecoderResultT . runDecoder dr p---- |--- Using the 'ParseFn', complete a 'DecodeResult' to find out if we have the type we're after. This--- is mostly used internally to help build 'Decoder' structures. Exported as it may prove useful--- when abstracting over the 'Decoder' types or other such shenanigans.-runDecodeResult- :: Monad f- => ParseFn- -> DecodeResult f a- -> f (Either (DecodeError, CursorHistory) a)-runDecodeResult p =- DI.runDecoderResultT- . flip runReaderT p- . unDecodeResult---- | Basic usage of a 'Decoder' is to specialise the 'f' to be 'Identity', then--- provide the 'ParseFn' and the 'ByteString' input. This will run the 'Decoder' to--- try to parse and decode the JSON to the 'a' you require.------ This function takes care of converting the 'ByteString' to a 'JCurs'.------ @--- simpleDecode (list int) myParseFn "[1,2,3]"--- =--- Right [1,2,3]--- @----simpleDecode- :: Decoder Identity a- -> ParseFn- -> ByteString- -> Either (DecodeError, CursorHistory) a-simpleDecode d parseFn =- runPureDecode d parseFn- . mkCursor---- | Helper function to handle wrapping up a parse failure using the given--- parsing function. Intended to be used with the 'runDecode' or 'simpleDecode'--- functions.------ @--- import Data.Attoparsec.ByteString (parseOnly)------ simpleDecode (list int) (parseWith (parseOnly parseWaargonaut)) "[1,1,2]"--- @----parseWith- :: ( CharParsing f- , Show e- )- => (f a -> i -> Either e a)- -> f a- -> i- -> Either DecodeError a-parseWith f p =- over _Left (ParseFailed . Text.pack . show) . f p---- | Similar to the 'simpleDecode' function, however this function expects--- you've already converted your input to a 'JCurs'.-runPureDecode- :: Decoder Identity a- -> ParseFn- -> JCurs- -> Either (DecodeError, CursorHistory) a-runPureDecode dr p =- runIdentity . runDecode dr p---- | This function lets you override the parsing function that is being used in--- a decoder for a different one. This means that when building your 'Decoder' you--- are not bound to only using a single parsing function. If you have specific--- needs for alternate parsers then you can use this function in your 'Decoder' to--- make that change.------ @--- myTricksyObj = withCursor $ \curs -> do--- curs' <- down curs--- fA <- fromKey "normalFieldA" int curs'--- fB <- fromKey "normalFieldB" text curs'--- wB <- overrideParser handTunedParser $ fromKey "weirdFieldC" fieldCDecoder curs'--- pure $ Foo fA fB wB--- @----overrideParser- :: Monad f- => ParseFn- -> DecodeResult f a- -> DecodeResult f a-overrideParser parseOverride =- local (const parseOverride) -- | Decoder for some 'Integral' type. This conversion is walked through Mayan, -- I mean, 'Scientific' to try to avoid numeric explosion issues.
src/Waargonaut/Decode/Internal.hs view
@@ -47,57 +47,58 @@ , module Waargonaut.Decode.ZipperMove ) where -import Control.Applicative (liftA2, (<|>))-import Control.Lens (Rewrapped, Wrapped (..), (%=),- _1, _Wrapped)-import qualified Control.Lens as L-import Control.Monad ((>=>))-import Control.Monad.Except (ExceptT (..), MonadError (..),- liftEither, runExceptT)-import Control.Monad.State (MonadState (..), StateT (..))-import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Applicative (liftA2, (<|>))+import Control.Lens (Rewrapped, Wrapped (..), (%=),+ _1, _Wrapped)+import qualified Control.Lens as L+import Control.Monad ((>=>))+import Control.Monad.Except (ExceptT (..), MonadError (..),+ liftEither, runExceptT)+import Control.Monad.State (MonadState (..), StateT (..))+import Control.Monad.Trans.Class (MonadTrans (lift)) -import Control.Monad.Error.Hoist ((<!?>))-import Control.Monad.Morph (MFunctor (..), MMonad (..))+import Control.Monad.Error.Hoist ((<!?>))+import Control.Monad.Morph (MFunctor (..), MMonad (..)) -import Data.Bifunctor (first)-import qualified Data.Foldable as F-import Data.Functor (($>))-import Data.Semigroup ((<>))-import Data.Sequence (Seq, fromList)+import Data.Bifunctor (first)+import qualified Data.Foldable as F+import Data.Functor (($>))+import Data.Semigroup ((<>))+import Data.Sequence (Seq, fromList) -import Data.ByteString (ByteString)-import qualified Data.ByteString.Lazy as BL-import qualified Data.ByteString.Lazy.Builder as BB-import Data.Text (Text)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Lazy.Builder as BB+import Data.Text (Text) -import Data.Map (Map)-import qualified Data.Map as Map+import Data.Map (Map)+import qualified Data.Map as Map -import qualified Data.Vector as V+import qualified Data.Vector as V -import qualified Data.Witherable as Wither+import qualified Data.Witherable as Wither -import Data.Scientific (Scientific)-import qualified Data.Scientific as Sci+import Data.Scientific (Scientific)+import qualified Data.Scientific as Sci -import Natural (Natural, _Natural)+import Natural (Natural, _Natural) -import Waargonaut.Types (AsJType (..), JString,- jCharBuilderByteStringL,- jNumberToScientific,- jsonAssocKey, jsonAssocVal,- _JChar, _JStringText)-import Waargonaut.Types.CommaSep (toList)-import Waargonaut.Types.JChar (jCharToUtf8Char)+import Waargonaut.Types (AsJType (..), JString,+ jNumberToScientific,+ jsonAssocKey, jsonAssocVal,+ _JStringText) -import Text.PrettyPrint.Annotated.WL (Doc, (<+>))+import Waargonaut.Types.CommaSep (toList)+import Waargonaut.Types.JChar (jCharToChar, jCharToUtf8Char) -import Waargonaut.Decode.Error (AsDecodeError (..),- DecodeError (..))-import Waargonaut.Decode.ZipperMove (ZipperMove (..), ppZipperMove)+import Text.PrettyPrint.Annotated.WL (Doc, (<+>)) +import Waargonaut.Decode.Error (AsDecodeError (..),+ DecodeError (..))+import Waargonaut.Decode.ZipperMove (ZipperMove (..), ppZipperMove) +import Waargonaut.Encode.Builder (bsBuilder)+import Waargonaut.Encode.Builder.JChar (jCharBuilder) -- | -- Track the history of the cursor as we move around the zipper. --@@ -302,7 +303,7 @@ -- | Try to decode a 'String' value from some 'Json' or value. string' :: AsJType a ws a => a -> Maybe String-string' = L.preview (_JStr . _1 . _Wrapped . L.to (V.toList . V.map (_JChar L.#)))+string' = L.preview (_JStr . _1 . _Wrapped . L.to (V.toList . V.map jCharToChar)) -- | Try to decode a 'Data.ByteString.ByteString' value from some 'Json' or value. strictByteString' :: AsJType a ws a => a -> Maybe ByteString@@ -311,7 +312,7 @@ -- | Try to decode a 'Data.ByteString.Lazy.ByteString' value from some 'Json' or value. lazyByteString' :: AsJType a ws a => a -> Maybe BL.ByteString lazyByteString' = L.preview (_JStr . _1 . _Wrapped . L.to mkBS)- where mkBS = BB.toLazyByteString . foldMap jCharBuilderByteStringL+ where mkBS = BB.toLazyByteString . foldMap (jCharBuilder bsBuilder) -- | Decoder for a 'Char' value that cannot contain values in the range U+D800 -- to U+DFFF. This decoder will fail if the 'Char' is outside of this range.@@ -321,7 +322,7 @@ -- | Decoder for a Haskell 'Char' value whose values represent Unicode -- (or equivalently ISO/IEC 10646) characters unboundedChar' :: AsJType a ws a => a -> Maybe Char-unboundedChar' = L.preview (_JStr . _1 . _Wrapped . L._head . L.re _JChar)+unboundedChar' = L.preview (_JStr . _1 . _Wrapped . L._head . L.to jCharToChar) -- | Try to decode a 'Scientific' value from some 'Json' or value. scientific' :: AsJType a ws a => a -> Maybe Scientific
+ src/Waargonaut/Decode/Runners.hs view
@@ -0,0 +1,267 @@+{-# LANGUAGE RankNTypes #-}+module Waargonaut.Decode.Runners+ (+ -- * General over @f@+ decodeWithInput+ , decodeFromString+ , decodeFromText+ , decodeFromByteString++ -- * Identity+ , pureDecodeWithInput+ , pureDecodeFromText+ , pureDecodeFromByteString+ , pureDecodeFromString++ -- * Helpers+ , overrideParser+ , parseWith++ ) where++import Prelude (Show, String, show)++import Control.Category (id, (.))+import Control.Monad (Monad (..))++import Control.Monad.Reader (local)++import Data.Bifunctor (first)+import Data.Either (Either (..))+import Data.Function (const)+import Data.Functor.Identity (Identity, runIdentity)++import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text++import Text.Parser.Char (CharParsing)++import Data.ByteString (ByteString)++import Waargonaut.Decode.Error (DecodeError (..))+import Waargonaut.Types++import qualified Waargonaut.Decode.Internal as DI++import Waargonaut.Decode.Types (CursorHistory, DecodeResult (..),+ Decoder (..), mkCursor)++-- | General decoding function that takes a given parsing function and some+-- functions to handle the transition from the input of the 'JCurs' to the+-- desired input type. The indexer and cursor requires a 'ByteString' to work+-- efficiently, but this does not preclude the use of other text types, provided+-- the right functions are present.+--+-- There are some specialised versions of this function provided for 'Text',+-- 'String', and 'ByteString'. They are implemented using this function, for+-- example to work with 'Text' input and the 'attoparsec' package:+--+-- @+-- import qualified Data.Attoparsec.Text as AT+-- import qualified Data.Text as Text+--+-- textDecode :: Monad g => Decoder g x -> Text -> g (Either (DecodeError, CursorHistory) x)+-- textDecode = decodeWithInput AT.parseOnly Text.decodeUtf8 Text.encodeUtf8+-- @+--+decodeWithInput+ :: ( CharParsing f+ , Show e+ , Monad g+ , Monad f+ )+ => (forall a. f a -> i -> Either e a)+ -> (ByteString -> i)+ -> (i -> ByteString)+ -> Decoder g x+ -> i+ -> g (Either (DecodeError, CursorHistory) x)+decodeWithInput parserFn toI fromI decode = DI.runDecoderResultT+ . runDecoder decode (parseWith parserFn parseWaargonaut . toI)+ . mkCursor+ . fromI++-- | As per the 'decodeWithInput' function, but with the input type specialised+-- to 'String'.+--+-- This function goes via 'Data.Text.Text' to ensure the UTF-8 is handled as+-- best as we can.+--+decodeFromString+ :: ( CharParsing f+ , Monad f+ , Monad g+ , Show e+ )+ => (forall a. f a -> String -> Either e a)+ -> Decoder g x+ -> String+ -> g (Either (DecodeError, CursorHistory) x)+decodeFromString parseFn = decodeWithInput parseFn+ (Text.unpack . Text.decodeUtf8)+ (Text.encodeUtf8 . Text.pack)++-- | As per 'decodeWithInput' function but specialised to the 'ByteString' input type.+decodeFromByteString+ :: ( CharParsing f+ , Monad f+ , Monad g+ , Show e+ )+ => (forall a. f a -> ByteString -> Either e a)+ -> Decoder g x+ -> ByteString+ -> g (Either (DecodeError, CursorHistory) x)+decodeFromByteString parseFn =+ decodeWithInput parseFn id id++-- | As per 'decodeWithInput' function but specialised to the 'Text' input type.+--+-- An example:+--+-- @+-- textDecode :: Decoder f a -> f (Either (DecodeError, CursorHistory) a)+-- textDecode = decodeFromText AT.parseOnly+-- @+--+decodeFromText+ :: ( CharParsing f+ , Monad f+ , Monad g+ , Show e+ )+ => (forall a. f a -> Text -> Either e a)+ -> Decoder g x+ -> Text+ -> g (Either (DecodeError, CursorHistory) x)+decodeFromText parseFn =+ decodeWithInput parseFn Text.decodeUtf8 Text.encodeUtf8++-- | This function works using one of the 'decodeFrom*' functions and provides a+-- pure decoder that demands the 'Decoder' but specialised to 'Identity'.+-- 'Decoder's are often to be general in their @g@ type so most are fine to use+-- this function. It is offered as a convenience and can be used like so:+--+-- @+-- import qualified Data.Attoparsec.Text as AT+-- import qualified Data.Text as Text+--+-- pureTextDecode :: Decoder Identity x -> Text -> Either (DecodeError, CursorHistory) x+-- pureTextDecode = pureDecodeWithInput decodeWithText AT.parseOnly+-- @+--+pureDecodeWithInput+ :: ( Monad f+ , CharParsing f+ , Show e+ )+ => ( forall g. Monad g+ => (forall a. f a -> i -> Either e a)+ -> Decoder g x+ -> i+ -> g (Either (DecodeError, CursorHistory) x)+ )+ -> (forall a. f a -> i -> Either e a)+ -> Decoder Identity x+ -> i+ -> Either (DecodeError, CursorHistory) x+pureDecodeWithInput decodeRunner parseFn decoder =+ runIdentity . decodeRunner parseFn decoder++-- | As per 'pureDecodeWithInput' but specialised to 'Data.Text.Text'.+pureDecodeFromText+ :: ( Monad f+ , CharParsing f+ , Show e+ )+ => (forall a. f a -> Text -> Either e a)+ -> Decoder Identity x+ -> Text+ -> Either (DecodeError, CursorHistory) x+pureDecodeFromText =+ pureDecodeWithInput decodeFromText++-- | As per 'pureDecodeWithInput' but specialised to 'Data.ByteString.ByteString'.+pureDecodeFromByteString+ :: ( Monad f+ , CharParsing f+ , Show e+ )+ => (forall a. f a -> ByteString -> Either e a)+ -> Decoder Identity x+ -> ByteString+ -> Either (DecodeError, CursorHistory) x+pureDecodeFromByteString =+ pureDecodeWithInput decodeFromByteString++-- | As per 'pureDecodeWithInput' but specialised to 'Data.String.String'.+--+pureDecodeFromString+ :: ( Monad f+ , CharParsing f+ , Show e+ )+ => (forall a. f a -> String -> Either e a)+ -> Decoder Identity x+ -> String+ -> Either (DecodeError, CursorHistory) x+pureDecodeFromString =+ pureDecodeWithInput decodeFromString++-- | Helper function to handle wrapping up a parse failure using the given+-- parsing function. Intended to be used with the 'runDecode' or 'simpleDecode'+-- functions.+--+-- @+-- import Data.Attoparsec.ByteString (parseOnly)+--+-- simpleDecode (list int) (parseWith (parseOnly parseWaargonaut)) "[1,1,2]"+-- @+--+parseWith+ :: ( CharParsing f+ , Show e+ )+ => (f a -> i -> Either e a)+ -> f a+ -> i+ -> Either DecodeError a+parseWith f p =+ first (ParseFailed . Text.pack . show) . f p++-- | This function lets you override the parsing function that is being used in+-- a decoder for a different one. This means that when building your 'Decoder' you+-- are not bound to only using a single parsing function. If you have specific+-- needs for alternate parsers then you can use this function in your 'Decoder' to+-- make that change.+--+-- Similar to the other decoding functions, this operation allows you to specify+-- your own parsing function and if necessary a 'ByteString -> i' conversion.+--+-- @+--+-- parseUsingByteString :: (Show e, CharParsing f, Monad f) => f a -> ByteString -> Either e a+-- parseUsingByteString = ...+--+-- myTricksyObj = withCursor $ \curs -> do+-- curs' <- down curs+-- fA <- fromKey "normalFieldA" int curs'+-- fB <- fromKey "normalFieldB" text curs'+-- wB <- overrideParser parseUsingByteString id handTunedParser $ fromKey "weirdFieldC" fieldCDecoder curs'+-- pure $ Foo fA fB wB+-- @+--+overrideParser+ :: ( CharParsing g+ , Monad g+ , Monad f+ , Show e+ )+ => (forall x. g x -> i -> Either e x)+ -> (ByteString -> i)+ -> g Json+ -> DecodeResult f a+ -> DecodeResult f a+overrideParser newParseFn floop parser =+ local (const (parseWith newParseFn parser . floop))
src/Waargonaut/Decode/Traversal.hs view
@@ -15,7 +15,8 @@ -- comparison. It is not as fast as the succinct data structure based -- 'Waargonaut.Decode.Decoder'. ---module Waargonaut.Decode.Traversal+module Waargonaut.Decode.Traversal + {-# DEPRECATED "Use 'Waargonaut.Decode'. This module will be removed in a future release." #-} ( Err (..) , CursorHistory (..)@@ -74,7 +75,6 @@ , maybeOrNull , withDefault , either- ) where import Prelude hiding (either, maybe, null)
src/Waargonaut/Decode/Types.hs view
@@ -14,6 +14,7 @@ , Decoder (..) , DecodeResult (..) , JCurs (..)+ , mkCursor , jsonTypeAt , JsonType(..) ) where@@ -37,8 +38,10 @@ import Data.Vector.Storable (Vector) import HaskellWorks.Data.BalancedParens (SimpleBalancedParens)+import HaskellWorks.Data.FromByteString (fromByteString) import HaskellWorks.Data.Json.Cursor (JsonCursor (..))-import HaskellWorks.Data.Json.Type (JsonType (..), JsonTypeAt (..))+import HaskellWorks.Data.Json.Type (JsonType (..),+ JsonTypeAt (..)) import HaskellWorks.Data.Positioning (Count) import HaskellWorks.Data.RankSelect.Poppy512 (Poppy512) @@ -58,8 +61,8 @@ type SuccinctCursor = JsonCursor ByteString Poppy512 (SimpleBalancedParens (Vector Word64)) --- | Another convenience alias for the type of the function we will use to parse the input string--- into the 'Json' structure.+-- Another convenience alias for the type of the function we will use to parse+-- the input string into the 'Json' structure. type ParseFn = ByteString -> Either DecodeError Json @@ -105,6 +108,11 @@ instance Wrapped JCurs where type Unwrapped JCurs = SuccinctCursor _Wrapped' = iso unJCurs JCurs++-- | Take a 'ByteString' input and build an index of the JSON structure inside+--+mkCursor :: ByteString -> JCurs+mkCursor = JCurs . fromByteString -- | Provide some of the type parameters that the underlying 'DecodeResultT' -- requires. This contains the state and error management as we walk around our
src/Waargonaut/Encode.hs view
@@ -24,8 +24,16 @@ -- * Runners , runPureEncoder , runEncoder- , simpleEncodeNoSpaces- , simplePureEncodeNoSpaces+ , simpleEncodeWith+ , simplePureEncodeWith+ , simpleEncodeText+ , simpleEncodeTextNoSpaces+ , simpleEncodeByteString+ , simpleEncodeByteStringNoSpaces+ , simplePureEncodeText+ , simplePureEncodeTextNoSpaces+ , simplePureEncodeByteString+ , simplePureEncodeByteStringNoSpaces -- * Provided encoders , int@@ -44,6 +52,7 @@ , mapToObj , json , prismE+ , asJson -- * Object encoder helpers , mapLikeObj@@ -81,6 +90,7 @@ , mapToObj' , keyValuesAsObj' , json'+ , asJson' , generaliseEncoder ) where @@ -93,10 +103,6 @@ (?~), _Empty, _Wrapped) import qualified Control.Lens as L -import Prelude (Bool, Int, Integral,- Monad, String,- fromIntegral, fst)- import Data.Foldable (Foldable, foldr, foldrM) import Data.Function (const, flip, ($), (&)) import Data.Functor (Functor, fmap)@@ -104,6 +110,9 @@ import Data.Functor.Contravariant.Divisible (divide) import Data.Functor.Identity (Identity (..)) import Data.Traversable (Traversable, traverse)+import Prelude (Bool, Int, Integral,+ Monad, String,+ fromIntegral, fst) import Data.Either (Either) import qualified Data.Either as Either@@ -117,7 +126,11 @@ import Data.Map (Map) import qualified Data.Map as Map+import Data.String (IsString) +import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Lazy.Builder as BB+ import Data.Text (Text) import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Builder as TB@@ -135,13 +148,15 @@ JAssoc (..), JObject, Json, MapLikeObj (..), WS, stringToJString,- toMapLikeObj, wsRemover,+ toMapLikeObj, _JNumberInt, _JNumberScientific, _JStringText) -import Waargonaut.Types.Json (waargonautBuilder)-+import Waargonaut.Encode.Builder (textBuilder, bsBuilder,+ waargonautBuilder)+import Waargonaut.Encode.Builder.Types (Builder)+import Waargonaut.Encode.Builder.Whitespace (wsBuilder, wsRemover) -- | Create an 'Encoder'' for 'a' by providing a function from 'a -> f Json'. encodeA :: (a -> f Json) -> Encoder f a@@ -152,26 +167,118 @@ encodePureA :: (a -> Json) -> Encoder' a encodePureA f = encodeA (Identity . f) --- | Encode an @a@ directly to a 'ByteString' using the provided 'Encoder'.-simpleEncodeNoSpaces+-- | Encode an @a@ directly to some output text type using the provided+-- 'Waargonaut.Encode.Builder.Types.Builder' and 'Encoder'.+simpleEncodeWith+ :: ( Applicative f+ , Monoid b+ , IsString t+ )+ => Builder t b+ -> (b -> out)+ -> (Builder t b -> WS -> b)+ -> Encoder f a+ -> a+ -> f out+simpleEncodeWith builder buildRunner wsB enc =+ fmap (buildRunner . waargonautBuilder wsB builder) . runEncoder enc++-- | Encode an @a@ directly to a 'LT.Text' using the provided 'Encoder'.+simpleEncodeText :: Applicative f => Encoder f a -> a -> f LT.Text-simpleEncodeNoSpaces enc =- fmap (TB.toLazyText . waargonautBuilder wsRemover) . runEncoder enc+simpleEncodeText =+ simpleEncodeWith textBuilder TB.toLazyText wsBuilder --- | As per 'simpleEncodeNoSpaces' but specialised the 'f' to 'Data.Functor.Identity' and remove it.-simplePureEncodeNoSpaces+-- | Encode an @a@ directly to a 'LT.Text' using the provided 'Encoder'.+simpleEncodeTextNoSpaces+ :: Applicative f+ => Encoder f a+ -> a+ -> f LT.Text+simpleEncodeTextNoSpaces =+ simpleEncodeWith textBuilder TB.toLazyText wsRemover++-- | Encode an @a@ directly to a 'BL.ByteString' using the provided 'Encoder'.+simpleEncodeByteString+ :: Applicative f+ => Encoder f a+ -> a+ -> f BL.ByteString+simpleEncodeByteString =+ simpleEncodeWith bsBuilder BB.toLazyByteString wsBuilder++-- | Encode an @a@ directly to a 'BL.ByteString' using the provided 'Encoder'.+simpleEncodeByteStringNoSpaces+ :: Applicative f+ => Encoder f a+ -> a+ -> f BL.ByteString+simpleEncodeByteStringNoSpaces =+ simpleEncodeWith bsBuilder BB.toLazyByteString wsRemover++-- | Encode an @a@ directly to a 'LT.Text' using the provided 'Encoder'.+simplePureEncodeWith+ :: ( Monoid b+ , IsString t+ )+ => Builder t b+ -> (b -> out)+ -> (Builder t b -> WS -> b)+ -> Encoder Identity a+ -> a+ -> out+simplePureEncodeWith builder buildRunner wsB enc =+ runIdentity . simpleEncodeWith builder buildRunner wsB enc++-- | As per 'simpleEncodeText' but specialised the 'f' to 'Data.Functor.Identity'.+simplePureEncodeText :: Encoder Identity a -> a -> LT.Text-simplePureEncodeNoSpaces enc =- runIdentity . simpleEncodeNoSpaces enc+simplePureEncodeText enc =+ runIdentity . simpleEncodeText enc +-- | As per 'simpleEncodeTextNoSpaces' but specialised the 'f' to 'Data.Functor.Identity'.+simplePureEncodeTextNoSpaces+ :: Encoder Identity a+ -> a+ -> LT.Text+simplePureEncodeTextNoSpaces enc =+ runIdentity . simpleEncodeTextNoSpaces enc++-- | As per 'simpleEncodeByteString' but specialised the 'f' to 'Data.Functor.Identity'.+simplePureEncodeByteString+ :: Encoder Identity a+ -> a+ -> BL.ByteString+simplePureEncodeByteString enc =+ runIdentity . simpleEncodeByteString enc++-- | As per 'simpleEncodeByteStringNoSpaces' but specialised the 'f' to 'Data.Functor.Identity'.+simplePureEncodeByteStringNoSpaces+ :: Encoder Identity a+ -> a+ -> BL.ByteString+simplePureEncodeByteStringNoSpaces enc =+ runIdentity . simpleEncodeByteStringNoSpaces enc++-- | Transform the given input using the 'Encoder' to its 'Json' data structure representation.+asJson :: Applicative f => Encoder f a -> a -> f Json+asJson e = runEncoder e+{-# INLINE asJson #-}++-- | As per 'asJson', but with the 'Encoder' specialised to 'Identity'+asJson' :: Encoder Identity a -> a -> Json+asJson' e = runIdentity . runEncoder e+{-# INLINE asJson' #-}+ -- | 'Encoder'' for a Waargonaut 'Json' data structure json :: Applicative f => Encoder f Json json = encodeA pure+{-# INLINE json #-} -- Internal function for creating an 'Encoder' from an 'Control.Lens.AReview'. encToJsonNoSpaces@@ -191,6 +298,7 @@ -> Encoder f b prismE p e = L.review p >$< e+{-# INLINE prismE #-} -- | Encode an 'Int' int :: Applicative f => Encoder f Int@@ -409,7 +517,7 @@ -> t -> t atKey' k enc v =- at k ?~ runIdentity (runEncoder enc v)+ at k ?~ asJson' enc v -- | Encode an 'Int' at the given 'Text' key. intAt@@ -502,7 +610,7 @@ -- intAt \"Height\" (_imageH img) . -- textAt \"Title\" (_imageTitle img) . -- boolAt \"Animated\" (_imageAnimated img) .--- arrayAt int \"IDs\" (_imageIDs img) -- ^ Set an @[Int]@ value at the \"IDs\" key.+-- listAt int \"IDs\" (_imageIDs img) -- ^ Set an @[Int]@ value at the \"IDs\" key. -- @ -- mapLikeObj@@ -585,8 +693,8 @@ -> ObjEncoder f b -> ObjEncoder f c -> ObjEncoder f a-combineObjects f eB eC =- divide f eB eC+combineObjects =+ divide -- | When encoding a JSON object that may contain duplicate keys, this function -- works the same as the 'atKey' function for 'MapLikeObj'.@@ -598,7 +706,7 @@ -> JObject WS Json -> f (JObject WS Json) onObj k b encB o = (\j -> o & _Wrapped L.%~ L.cons j)- . JAssoc (_JStringText # k) mempty mempty <$> runEncoder encB b+ . JAssoc (_JStringText # k) mempty mempty <$> asJson encB b -- | Encode key value pairs as a JSON object, allowing duplicate keys. keyValuesAsObj@@ -618,8 +726,8 @@ ) => Encoder f a -> Encoder f (g (Text, a))-keyValueTupleFoldable eA = encodeA $ \xs ->- (\v -> _JObj # (v,mempty)) <$> foldrM (\(k,v) o -> onObj k v eA o) (_Empty # ()) xs+keyValueTupleFoldable eA = encodeA $+ fmap (\v -> _JObj # (v,mempty)) . foldrM (\(k,v) o -> onObj k v eA o) (_Empty # ()) -- | As per 'keyValuesAsObj' but with the 'f' specialised to 'Identity'. keyValuesAsObj'
+ src/Waargonaut/Encode/Builder.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE RankNTypes #-}+module Waargonaut.Encode.Builder where++import Data.String (IsString, fromString)++import Data.Monoid ((<>))++import Data.Text (Text)+import qualified Data.Text.Lazy.Builder as T+import qualified Data.Text.Lazy.Builder.Int as T++import Data.ByteString (ByteString)+import qualified Data.ByteString.Builder as B++import Waargonaut.Types.Json (JType (..), Json (..))+import Waargonaut.Types.Whitespace (WS)++import Waargonaut.Encode.Builder.JArray (jArrayBuilder)+import Waargonaut.Encode.Builder.JNumber (jNumberBuilder)+import Waargonaut.Encode.Builder.JObject (jObjectBuilder)+import Waargonaut.Encode.Builder.JString (jStringBuilder)+import Waargonaut.Encode.Builder.Types (Builder (..))++textBuilder :: Builder Text T.Builder+textBuilder = Builder+ T.singleton+ T.fromText+ T.decimal++bsBuilder :: Builder ByteString B.Builder+bsBuilder = Builder+ B.charUtf8+ B.byteString+ B.intDec++jTypesBuilder+ :: ( IsString t+ , Monoid b+ )+ => Builder t b+ -> (Builder t b -> WS -> b)+ -> JType WS Json+ -> b+jTypesBuilder bldr s jt =+ let+ (jBuilt, tws') = case jt of+ JNull tws -> (fromChunk bldr (fromString "null"), tws)+ JBool b tws -> (fromChunk bldr (fromString $ if b then "true" else "false"), tws)+ JNum jn tws -> (jNumberBuilder bldr jn, tws)+ JStr js tws -> (jStringBuilder bldr js, tws)+ JArr js tws -> (jArrayBuilder bldr s waargonautBuilder js, tws)+ JObj jobj tws -> (jObjectBuilder bldr s waargonautBuilder jobj, tws)+ in+ jBuilt <> s bldr tws'++-- | Using the given whitespace builder, create a builder for a given 'Json' value.+waargonautBuilder+ :: ( IsString t+ , Monoid b+ )+ => (Builder t b -> WS -> b)+ -> Builder t b+ -> Json+ -> b+waargonautBuilder ws bldr (Json jt) =+ jTypesBuilder bldr ws jt
+ src/Waargonaut/Encode/Builder/CommaSep.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE RankNTypes #-}+module Waargonaut.Encode.Builder.CommaSep (commaSeparatedBuilder) where++import Data.Monoid ((<>))+import Waargonaut.Types.CommaSep (Comma, CommaSeparated (..),+ Elem (..), Elems (..))++import Waargonaut.Encode.Builder.Types (Builder (..))++-- | Builder for UTF8 Comma+commaBuilder :: Builder t b -> b+commaBuilder b = fromChar b ','+{-# INLINE commaBuilder #-}++-- | Builder for a comma and trailing whitespace combination.+commaTrailingBuilder+ :: ( Monoid b+ , Foldable f+ )+ => Builder t b+ -> (Builder t b -> ws -> b)+ -> f (Comma, ws)+ -> b+commaTrailingBuilder bldr wsB =+ foldMap ((commaBuilder bldr <>) . (wsB bldr) . snd)++-- | Using the given builders for the whitespace and elements ('a'), create a+-- builder for a 'CommaSeparated'.+commaSeparatedBuilder+ :: forall ws a t b. Monoid b+ => Builder t b+ -> Char+ -> Char+ -> (Builder t b -> ws -> b)+ -> (Builder t b -> a -> b)+ -> CommaSeparated ws a+ -> b+commaSeparatedBuilder bldr op fin wsB aB (CommaSeparated lws sepElems) =+ fromChar bldr op <> wsB bldr lws <> maybe mempty buildElems sepElems <> fromChar bldr fin+ where+ elemBuilder (Elem e eTrailing) =+ aB bldr e <> commaTrailingBuilder bldr wsB eTrailing++ buildElems (Elems es elst) =+ foldMap elemBuilder es <> elemBuilder elst
+ src/Waargonaut/Encode/Builder/JArray.hs view
@@ -0,0 +1,17 @@+module Waargonaut.Encode.Builder.JArray (jArrayBuilder) where++import Waargonaut.Types.JArray (JArray (..))++import Waargonaut.Encode.Builder.CommaSep (commaSeparatedBuilder)+import Waargonaut.Encode.Builder.Types (Builder)++-- | Using the given builders, build a 'JArray'.+jArrayBuilder+ :: Monoid b+ => Builder t b+ -> (Builder t b -> ws -> b)+ -> ((Builder t b -> ws -> b) -> Builder t b -> a -> b)+ -> JArray ws a+ -> b+jArrayBuilder bldr ws a (JArray cs) =+ commaSeparatedBuilder bldr '[' ']' ws (a ws) cs
+ src/Waargonaut/Encode/Builder/JChar.hs view
@@ -0,0 +1,34 @@+module Waargonaut.Encode.Builder.JChar (jCharBuilder) where++import Control.Lens (review)++import Data.Monoid ((<>))++import Data.Digit (HeXaDeCiMaL, charHeXaDeCiMaL)++import Waargonaut.Encode.Builder.Types (Builder (..))+import Waargonaut.Types.JChar (JChar (..))+import Waargonaut.Types.JChar.Escaped (Escaped (..))+import Waargonaut.Types.JChar.HexDigit4 (HexDigit4 (..))+import Waargonaut.Types.JChar.Unescaped (_Unescaped)+import Waargonaut.Types.Whitespace (unescapedWhitespaceChar)++-- | Using the given function, return the builder for a single 'JChar'.+jCharBuilder+ :: ( Monoid b+ , HeXaDeCiMaL digit+ )+ => Builder t b+ -> JChar digit+ -> b+jCharBuilder bldr (UnescapedJChar c) = fromChar bldr (review _Unescaped c)+jCharBuilder bldr (EscapedJChar jca) = fromChar bldr '\\' <> case jca of+ QuotationMark -> fromChar bldr '"'+ ReverseSolidus -> fromChar bldr '\\'+ Solidus -> fromChar bldr '/'+ Backspace -> fromChar bldr 'b'+ (WhiteSpace ws) -> fromChar bldr (unescapedWhitespaceChar ws)+ Hex (HexDigit4 a b c d) -> fromChar bldr 'u' <> foldMap hexChar [a,b,c,d]+ where+ hexChar =+ fromChar bldr . review charHeXaDeCiMaL
+ src/Waargonaut/Encode/Builder/JNumber.hs view
@@ -0,0 +1,85 @@+module Waargonaut.Encode.Builder.JNumber+ ( jNumberBuilder+ ) where++import Control.Lens (review)++import qualified Data.Digit as D+import Data.List.NonEmpty (NonEmpty)+import Data.Monoid ((<>))++import Waargonaut.Types.JNumber (E (..), Exp (..), Frac (..),+ JNumber (..), jIntToDigits)++import Waargonaut.Encode.Builder.Types (Builder (..))++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Data.List.NonEmpty (NonEmpty ((:|)))+-- >>> import Data.Digit (DecDigit(..))+-- >>> import qualified Data.Digit as D+-- >>> import Data.Text.Lazy.Builder (toLazyText)+-- >>> import Waargonaut.Encode.Builder (textBuilder)+-- >>> import Waargonaut.Types.JNumber (JInt' (JIntInt))+--++getExpSymbol+ :: Monoid b+ => Builder t b+ -> Maybe Bool+ -> b+getExpSymbol bldr (Just True) = fromChar bldr '-'+getExpSymbol bldr (Just False) = fromChar bldr '+'+getExpSymbol _ _ = mempty++eBuilder+ :: Monoid b+ => Builder t b+ -> E+ -> b+eBuilder bldr Ee = fromChar bldr 'e'+eBuilder bldr EE = fromChar bldr 'E'++fracBuilder :: Monoid b => Builder t b -> Frac -> b+fracBuilder bldr (Frac digs) = digitsBuilder bldr digs++digitsBuilder+ :: Monoid b+ => Builder t b+ -> NonEmpty D.DecDigit+ -> b+digitsBuilder bldr =+ foldMap (fromInt bldr . review D.integralDecimal)++-- | Builder for the exponent portion.+expBuilder+ :: Monoid b+ => Builder t b+ -> Exp+ -> b+expBuilder bldr (Exp e sign digs) =+ eBuilder bldr e <> getExpSymbol bldr sign <> digitsBuilder bldr digs++-- | Printing of JNumbers+--+-- >>> toLazyText $ jNumberBuilder textBuilder (JNumber {_minus = False, _numberint = JIntInt D.DecDigit3 [], _frac = Just (Frac (D.DecDigit4 :| [D.DecDigit5])), _expn = Just (Exp {_ex = Ee, _minusplus = Just False, _expdigits = D.DecDigit1 :| [D.DecDigit0]})})+-- "3.45e+10"+--+-- >>> toLazyText $ jNumberBuilder textBuilder (JNumber {_minus = True, _numberint = JIntInt D.DecDigit3 [], _frac = Just (Frac (D.DecDigit4 :| [D.DecDigit5])), _expn = Just (Exp {_ex = Ee, _minusplus = Just True, _expdigits = D.DecDigit0 :| [D.x2]})})+-- "-3.45e-02"+--+-- >>> toLazyText $ jNumberBuilder textBuilder (JNumber {_minus = False, _numberint = JIntInt D.DecDigit0 [D.DecDigit0], _frac = Nothing, _expn = Nothing})+-- "00"+--+jNumberBuilder+ :: Monoid b+ => Builder t b+ -> JNumber+ -> b+jNumberBuilder bldr (JNumber sign digs mfrac mexp) =+ s <> digits <> frac' <> expo+ where+ s = if sign then fromChar bldr '-' else mempty+ digits = digitsBuilder bldr . jIntToDigits $ digs+ frac' = foldMap (mappend (fromChar bldr '.') . fracBuilder bldr) mfrac+ expo = foldMap (expBuilder bldr) mexp
+ src/Waargonaut/Encode/Builder/JObject.hs view
@@ -0,0 +1,31 @@+module Waargonaut.Encode.Builder.JObject (jObjectBuilder) where++import Data.Monoid ((<>))++import Waargonaut.Types.JObject (JAssoc (..), JObject (..))++import Waargonaut.Encode.Builder.CommaSep (commaSeparatedBuilder)+import Waargonaut.Encode.Builder.JString (jStringBuilder)+import Waargonaut.Encode.Builder.Types (Builder (..))++-- | Builder for a single "key:value" pair.+jAssocBuilder+ :: Monoid b+ => (Builder t b -> ws -> b)+ -> ((Builder t b -> ws -> b) -> Builder t b -> a -> b)+ -> Builder t b+ -> JAssoc ws a+ -> b+jAssocBuilder ws aBuilder bldr (JAssoc k ktws vpws v) =+ jStringBuilder bldr k <> ws bldr ktws <> fromChar bldr ':' <> ws bldr vpws <> aBuilder ws bldr v++-- | Construct a 'Builder' for an entire 'JObject', duplicate keys are preserved.+jObjectBuilder+ :: Monoid b+ => Builder t b+ -> (Builder t b -> ws -> b)+ -> ((Builder t b -> ws -> b) -> Builder t b -> a -> b)+ -> JObject ws a+ -> b+jObjectBuilder bldr ws aBuilder (JObject c) =+ commaSeparatedBuilder bldr '{' '}' ws (jAssocBuilder ws aBuilder) c
+ src/Waargonaut/Encode/Builder/JString.hs view
@@ -0,0 +1,50 @@+module Waargonaut.Encode.Builder.JString (jStringBuilder) where++import Data.Monoid ((<>))++import Waargonaut.Types.JString (JString, JString' (..))++import Waargonaut.Encode.Builder.JChar (jCharBuilder)+import Waargonaut.Encode.Builder.Types (Builder (..))++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Data.Function (($))+-- >>> import Data.Digit (HeXDigit(..))+-- >>> import qualified Data.Vector as V+-- >>> import Waargonaut.Types.Whitespace+-- >>> import Waargonaut.Types.JChar.Unescaped+-- >>> import Waargonaut.Types.JChar.Escaped+-- >>> import Waargonaut.Types.JChar.HexDigit4+-- >>> import Waargonaut.Types.JChar+-- >>> import Waargonaut.Encode.Builder (textBuilder)+-- >>> import Data.Text.Lazy.Builder (toLazyText)+----++-- | Builder for a 'JString'.+--+-- >>> toLazyText $ jStringBuilder textBuilder ((JString' V.empty) :: JString)+-- "\"\""+--+-- >>> toLazyText $ jStringBuilder textBuilder ((JString' $ V.fromList [UnescapedJChar (Unescaped 'a'),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) :: JString)+-- "\"abc\""+--+-- >>> toLazyText $ jStringBuilder textBuilder ((JString' $ V.fromList [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) :: JString)+-- "\"a\\rbc\""+--+-- >>> toLazyText $ jStringBuilder textBuilder ((JString' $ V.fromList [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (Unescaped 'd'),UnescapedJChar (Unescaped 'e'),UnescapedJChar (Unescaped 'f'),EscapedJChar QuotationMark]) :: JString)+-- "\"a\\rbc\\uab12\\ndef\\\"\""+--+-- >>> toLazyText $ jStringBuilder textBuilder ((JString' $ V.singleton (UnescapedJChar (Unescaped 'a'))) :: JString)+-- "\"a\""+--+-- >>> toLazyText $ jStringBuilder textBuilder (JString' $ V.singleton (EscapedJChar ReverseSolidus) :: JString)+-- "\"\\\\\""+--+jStringBuilder+ :: Monoid b+ => Builder t b+ -> JString+ -> b+jStringBuilder bldr (JString' jcs) =+ fromChar bldr '\"' <> foldMap (jCharBuilder bldr) jcs <> fromChar bldr '\"'
+ src/Waargonaut/Encode/Builder/Types.hs view
@@ -0,0 +1,7 @@+module Waargonaut.Encode.Builder.Types (Builder (..)) where++data Builder t b = Builder+ { fromChar :: Char -> b+ , fromChunk :: t -> b+ , fromInt :: Int -> b+ }
+ src/Waargonaut/Encode/Builder/Whitespace.hs view
@@ -0,0 +1,29 @@+module Waargonaut.Encode.Builder.Whitespace+ ( whitespaceBuilder+ , wsBuilder+ , wsRemover+ ) where++import Data.Monoid (Monoid)+import Waargonaut.Types.Whitespace (WS (..), Whitespace (..))++import Waargonaut.Encode.Builder.Types (Builder (..))++-- | Create a 'Data.ByteString.Builder' from a 'Whitespace'+whitespaceBuilder :: Monoid b => Builder t b -> Whitespace -> b+whitespaceBuilder bldr Space = fromChar bldr ' '+whitespaceBuilder bldr HorizontalTab = fromChar bldr '\t'+whitespaceBuilder bldr LineFeed = fromChar bldr '\f'+whitespaceBuilder bldr CarriageReturn = fromChar bldr '\r'+whitespaceBuilder bldr NewLine = fromChar bldr '\n'+{-# INLINE whitespaceBuilder #-}++-- | Reconstitute the given whitespace into its original form.+wsBuilder :: Monoid b => Builder t b -> WS -> b+wsBuilder bldr (WS ws) = foldMap (whitespaceBuilder bldr) ws+{-# INLINE wsBuilder #-}++-- | Remove any whitespace. Minification for free, yay!+wsRemover :: Monoid b => Builder t b -> WS -> b+wsRemover _ = const mempty+{-# INLINE wsRemover #-}
src/Waargonaut/Generic.hs view
@@ -58,15 +58,16 @@ import Control.Lens (findOf, folded, isn't, _Left) import Control.Monad ((>=>)) import Control.Monad.Except (lift, throwError)+import Control.Monad.Reader (runReaderT) import Control.Monad.State (modify) -import Data.Functor.Identity (runIdentity)- import qualified Data.Char as Char import Data.Maybe (fromMaybe) import Data.List.NonEmpty (NonEmpty) +import Data.ByteString (ByteString)+ import Data.Text (Text) import qualified Data.Text as Text @@ -88,7 +89,9 @@ import Waargonaut.Decode.Error (DecodeError (..)) import Waargonaut.Decode.Internal (CursorHistory' (..),- DecodeResultT (..))+ DecodeResultT (..),+ runDecoderResultT)+import Waargonaut.Decode.Types (unDecodeResult) -- $setup -- >>> :set -XOverloadedStrings@@ -97,7 +100,7 @@ -- Although creating your 'Decoder's and 'Encoder's explicitly is the preferred way of utilising -- Waargonaut. The 'Generic' mechanism within Haskell provides immense opportunity to reduce or -- eliminate the need to write code. Given the mechanical nature of JSON this a benefit that cannot--- be ignored. +-- be ignored. -- -- There are two typeclasses provided, 'JsonEncode' and 'JsonDecode'. Each with a single function -- that will generate a 'Encoder' or 'Decoder' for that type. Normally, typeclasses such as these@@ -187,7 +190,7 @@ -- particularly useful; 'untag', and 'proxy'. -- -- The 'untag' function removes the tag from the inner type:--- +-- -- @ -- untag :: -- forall k (s :: k) b. Tagged s b -> b -- @@@ -421,7 +424,7 @@ tagVal NoTag v = K v tagVal (Tag t) v =- K $ runIdentity . E.runEncoder (inObj E.json' t) <$> v+ K $ E.asJson' (inObj E.json' t) <$> v unTagVal :: Monad f@@ -521,26 +524,26 @@ -> NP I xs -> K (f Json) xs gEncoder' _ _ _ (JsonZero n) Nil =- K (E.runEncoder (T.untag mkEncoder) (Text.pack n))+ K (E.asJson (T.untag mkEncoder) (Text.pack n)) gEncoder' _ pT _ (JsonOne tag) (I a :* Nil) =- tagVal tag $ E.runEncoder (T.proxy mkEncoder pT) a+ tagVal tag $ E.asJson (T.proxy mkEncoder pT) a gEncoder' p pT _ (JsonMul tag) cs =- tagVal tag . E.runEncoder (E.list E.json) . hcollapse $ hcliftA p ik cs+ tagVal tag . E.asJson (E.list E.json) . hcollapse $ hcliftA p ik cs where ik :: JsonEncode t x => I x -> K Json x- ik = K . runIdentity . E.runEncoder (T.proxy mkEncoder pT) . unI+ ik = K . E.asJson' (T.proxy mkEncoder pT) . unI gEncoder' p pT opts (JsonRec tag fields) cs = tagVal tag . enc . hcollapse $ hcliftA2 p tup fields cs where tup :: JsonEncode t x => K String x -> I x -> K (Text, Json) x tup f a = K ( modFieldName opts (unK f)- , runIdentity $ E.runEncoder (T.proxy mkEncoder pT) (unI a)+ , E.asJson' (T.proxy mkEncoder pT) (unI a) ) - enc = pure . E.runPureEncoder (E.keyValueTupleFoldable E.json)+ enc = pure . E.asJson' (E.keyValueTupleFoldable E.json) -- | -- Create a 'Tagged' 'Decoder' for type @ a @, tagged by @ t @, using the given 'Options'.@@ -583,7 +586,7 @@ ) => Options -> Proxy (All (JsonDecode t))- -> D.ParseFn+ -> (ByteString -> Either DecodeError Json) -> D.JCurs -> NP JsonInfo xss -> DecodeResultT Count DecodeError f (SOP I xss)@@ -598,11 +601,15 @@ failure (e,h) = modify (const h) >> throwError e + runDR = runDecoderResultT+ . flip runReaderT parseFn+ . unDecodeResult+ -- Pretty sure there is a better way to manage this, as my intuition about -- generic-sop says that I will only have one successful result for any -- given type. But I'm not 100% sure that this is actually the case. foldForRight :: [D.DecodeResult f (SOP I xss)] -> DecodeResultT Count DecodeError f (SOP I xss)- foldForRight xs = (lift . sequence $ D.runDecodeResult parseFn <$> xs)+ foldForRight xs = (lift . sequence $ runDR <$> xs) >>= either failure pure . fromMaybe err . findOf folded (isn't _Left) injs :: NP (Injection (NP I) xss) xss
+ src/Waargonaut/Lens.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeFamilies #-}+module Waargonaut.Lens+ (+ -- * Prisms+ _TextJson+ , _Number+ , _String+ , _Bool+ , _ArrayOf+ , _ObjHashMapOf+ , _Null+ ) where++import Prelude (Bool, Show)++import Control.Applicative (liftA2)+import Control.Category ((.))+import Control.Error.Util (note)+import Control.Lens (Prism', cons, preview, prism,+ review, (^?), _1, _Wrapped)+import Control.Monad (Monad, void)+import Data.Foldable (foldr)+import Data.Function (const, ($))+import Data.Functor (fmap)+import Data.Scientific (Scientific)+import Data.Tuple (uncurry)++import Data.Bifunctor (first)+import Data.Either (Either (..))++import Text.Parser.Char (CharParsing)++import Data.Text (Text)+import qualified Data.Text.Lazy as TL++import Data.Vector (Vector)+import qualified Data.Vector as V++import Data.HashMap.Strict (HashMap)+import qualified Data.HashMap.Strict as HM++import qualified Waargonaut.Types.JObject.JAssoc as JA++import qualified Waargonaut.Types.CommaSep as CS+import Waargonaut.Types.JString (_JStringText)++import Waargonaut.Types.JNumber (_JNumberScientific)+import Waargonaut.Types.Json (AsJType (..), Json)++import qualified Waargonaut.Decode as D+import qualified Waargonaut.Encode as E++-- | 'Prism'' between 'Json' and 'Text'+_TextJson+ :: ( CharParsing g+ , Monad g+ , Show e+ )+ => (forall a. g a -> Text -> Either e a)+ -> Prism' Text Json+_TextJson pf = prism+ (TL.toStrict . E.simplePureEncodeText E.json)+ (\b -> first (const b) $ D.pureDecodeFromText pf D.json b)+{-# INLINE _TextJson #-}++-- | 'Prism'' between some 'Json' and a 'Scientific' value+_Number :: Prism' Json Scientific+_Number = prism (E.asJson' E.scientific) (\j -> note j $ j ^? _JNum . _1 . _JNumberScientific)+{-# INLINE _Number #-}++-- | 'Prism'' between some 'Json' and a 'Text' value+_String :: Prism' Json Text+_String = prism (E.asJson' E.text) (\j -> note j $ j ^? _JStr . _1 . _JStringText)+{-# INLINE _String #-}++-- | 'Prism'' between some 'Json' and a '()' value+_Null :: Prism' Json ()+_Null = prism (E.asJson' E.null) (\j -> note j . void $ j ^? _JNull)+{-# INLINE _Null #-}++-- | 'Prism'' between some 'Json' and a 'Bool' value+_Bool :: Prism' Json Bool+_Bool = prism (E.asJson' E.bool) (\j -> note j $ j ^? _JBool . _1)+{-# INLINE _Bool#-}++-- | 'Prism'' between some 'Json' and an array of something given the provided 'Prism''+_ArrayOf :: Prism' Json x -> Prism' Json (Vector x)+_ArrayOf _Value = prism fromJ toJ+ where+ fromJ = E.asJson' (E.traversable E.json) . fmap (review _Value)+ {-# INLINE fromJ #-}+ toJ = CS.fromCommaSep (_JArr . _1 . _Wrapped) V.empty (foldr cons V.empty) (preview _Value)+ {-# INLINE toJ #-}+{-# INLINE _ArrayOf #-}++-- | 'Prism'' between some 'Json' and a strict 'HashMap' with 'Text' keys, and+-- some value of a type provided by the given @Prism' Json x@.+_ObjHashMapOf :: Prism' Json x -> Prism' Json (HashMap Text x)+_ObjHashMapOf _Value = prism toJ fromJ+ where+ toJ = E.asJson' (E.keyValueTupleFoldable (E.prismE _Value E.json)) . HM.toList+ {-# INLINE toJ #-}++ toVals el = liftA2 (,)+ (preview (JA.jsonAssocKey . _JStringText) el)+ (preview (JA.jsonAssocVal . _Value) el)+ {-# INLINE toVals #-}++ fromJ = CS.fromCommaSep (_JObj . _1 . _Wrapped) HM.empty+ (foldr (uncurry HM.insert) HM.empty) toVals+ {-# INLINE fromJ #-}+{-# INLINE _ObjHashMapOf #-}
src/Waargonaut/Prettier.hs view
@@ -13,41 +13,45 @@ , simpleEncodePretty ) where -import Prelude (Eq, Show, (+), (-))+import Prelude (Eq, Show, (+), (-)) -import Control.Applicative (Applicative, (<$>))-import Control.Category (id, (.))-import Control.Lens (Traversal', over, traverseOf,- (%~), (.~), _1, _2, _Just,- _Wrapped)+import Control.Applicative (Applicative, (<$>))+import Control.Category (id, (.))+import Control.Lens (Traversal', over,+ traverseOf, (%~), (.~),+ _1, _2, _Just, _Wrapped) -import Natural (Natural, minus, successor', zero',- _Natural)+import Natural (Natural, minus,+ successor', zero',+ _Natural) -import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Builder as TB+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Builder as TB -import Data.Bool (Bool, bool)-import Data.Foldable (elem, length)-import Data.Function (($))-import Data.Functor (fmap)-import Data.Maybe (maybe)-import Data.Semigroup ((<>))-import Data.Traversable (traverse)-import qualified Data.Vector as V+import Data.Bool (Bool, bool)+import Data.Foldable (elem, length)+import Data.Function (($))+import Data.Functor (fmap)+import Data.Maybe (maybe)+import Data.Semigroup ((<>))+import Data.Traversable (traverse)+import qualified Data.Vector as V -import qualified Control.Lens as L-import qualified Control.Lens.Plated as P+import qualified Control.Lens as L+import qualified Control.Lens.Plated as P -import Waargonaut.Encode (Encoder, runEncoder)-import Waargonaut.Types.CommaSep (Elems)-import qualified Waargonaut.Types.CommaSep as CS-import Waargonaut.Types.JObject (HasJAssoc (..), JAssoc)-import Waargonaut.Types.Json (AsJType (..), JType (..), Json,- jsonTraversal, waargonautBuilder)-import Waargonaut.Types.Whitespace (WS (..), Whitespace (..),- wsBuilder)+import Waargonaut.Encode (Encoder, runEncoder)+import Waargonaut.Types.CommaSep (Elems)+import qualified Waargonaut.Types.CommaSep as CS+import Waargonaut.Types.JObject (HasJAssoc (..), JAssoc)+import Waargonaut.Types.Json (AsJType (..), JType (..),+ Json, jsonTraversal)+import Waargonaut.Types.Whitespace (WS (..), Whitespace (..)) +import Waargonaut.Encode.Builder (textBuilder,+ waargonautBuilder)+import Waargonaut.Encode.Builder.Whitespace (wsBuilder)+ -- | Some choices for how the Json is indented. data InlineOption = ArrayOnly -- ^ Only keep array elements on the same line, input line breaks between object values.@@ -82,7 +86,7 @@ -> a -> f LT.Text simpleEncodePretty io step ind enc =- fmap (TB.toLazyText . waargonautBuilder wsBuilder . prettyJson io step ind)+ fmap (TB.toLazyText . waargonautBuilder wsBuilder textBuilder . prettyJson io step ind) . runEncoder enc objelems :: AsJType r WS a => Traversal' r (Elems WS (JAssoc WS a))
src/Waargonaut/Test.hs view
@@ -1,18 +1,16 @@+{-# LANGUAGE RankNTypes #-} -- | Helper functions for testing your 'Decoder' and 'Encoder' functions. -- module Waargonaut.Test ( roundTripSimple ) where -import qualified Data.Text.Encoding as Text-import qualified Data.Text.Lazy as TextL+import Data.Text (Text) -import Data.ByteString (ByteString)+import qualified Data.Text.Lazy as TextL import Text.Parser.Char (CharParsing) -import Waargonaut.Types (Json, parseWaargonaut)- import Waargonaut.Encode (Encoder) import qualified Waargonaut.Encode as E @@ -30,13 +28,11 @@ , Monad g , Show e )- => (f Json -> ByteString -> Either e Json)+ => (forall a. f a -> Text -> Either e a) -> Encoder g b -> Decoder g b -> b -> g (Either (DecodeError, CursorHistory) Bool) roundTripSimple f e d a = do- encodedA <- E.simpleEncodeNoSpaces e a- (fmap . fmap) (== a) $ D.runDecode d- (D.parseWith f parseWaargonaut)- (D.mkCursor . Text.encodeUtf8 . TextL.toStrict $ encodedA)+ encodedA <- E.simpleEncodeTextNoSpaces e a+ fmap (== a) <$> D.decodeFromText f d (TextL.toStrict encodedA)
src/Waargonaut/Types/CommaSep.hs view
@@ -1,15 +1,13 @@-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-} -- | Both arrays and objects in JSON allow for an optional trailing comma on the -- final element. This module houses the shared types and functions that let us -- handle this.@@ -23,202 +21,85 @@ , HasElem (..) , Comma (..) - -- * Parse / Build+ -- * Parse , parseComma- , commaBuilder , parseCommaSeparated- , commaSeparatedBuilder -- * Conversion , _CommaSeparated , toList , fromList+ , fromCommaSep -- * Cons / Uncons , consCommaSep , unconsCommaSep ) where -import Prelude (Eq, Int, Show (showsPrec),- showString, shows, (&&), (==), (||))+import Prelude (Eq, Int, Show, (&&), (==),+ (||)) -import Control.Applicative (Applicative (..), liftA2, pure, (*>),- (<*), (<*>))-import Control.Category (id, (.))+import Control.Applicative (Applicative (..), pure, (*>),+ (<*), (<*>))+import Control.Category ((.)) -import Control.Lens (AsEmpty (..), Cons (..), Index, Iso,- Iso', IxValue, Ixed (..), Lens',- Snoc (..), cons, from, iso,- mapped, nearly, over, prism, snoc, to,- traverse, unsnoc, (%%~), (%~), (.~),- (^.), (^..), (^?), _1, _2, _Cons,- _Just, _Nothing)-import Control.Lens.Extras (is)+import Control.Lens (AsEmpty (..), Cons (..), Traversal',+ Index, Iso, IxValue,+ Ixed (..), Snoc (..), cons,+ from, iso, mapped, nearly, preview,+ over, prism, snoc, to,+ traverse, unsnoc, (%%~), (%~),+ (.~), (^.), (^..), (^?), _1,+ _2, _Cons, _Just, _Nothing)+import Control.Lens.Extras (is) -import Control.Error.Util (note)-import Control.Monad (Monad)+import Control.Error.Util (note)+import Control.Monad (Monad) -import Data.Bifoldable (Bifoldable (bifoldMap))-import Data.Bifunctor (Bifunctor (bimap))-import Data.Bitraversable (Bitraversable (bitraverse))-import Data.Char (Char)-import Data.Either (Either (..))-import Data.Foldable (Foldable, asum, foldMap, foldr,- length)-import Data.Function (const, flip, ($), (&))-import Data.Functor (Functor, fmap, (<$), (<$>))-import Data.Functor.Classes (Eq1, Show1, eq1, showsPrec1)-import Data.Maybe (Maybe (..), fromMaybe, maybe)-import Data.Monoid (Monoid (..), mempty)-import Data.Semigroup (Semigroup ((<>)))-import Data.Traversable (Traversable)-import Data.Tuple (snd, uncurry)+import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Either (Either (..))+import Data.Foldable (Foldable, asum, foldMap,+ foldr, length)+import Data.Function (flip, ($), (&))+import Data.Functor (Functor, fmap, (<$), (<$>))+import Data.Maybe (Maybe (..), maybe)+import Data.Monoid (Monoid (..), mempty)+import Data.Semigroup (Semigroup ((<>)))+import Data.Traversable (Traversable)+import Data.Tuple (uncurry) -import Data.Vector (Vector)-import qualified Data.Vector as V+import qualified Data.Vector as V -import Data.Functor.Identity (Identity (..))+import Text.Parser.Char (CharParsing) -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB+import Data.Witherable (Filterable (..),+ Witherable (..)) -import Text.Parser.Char (CharParsing, char)-import qualified Text.Parser.Combinators as C+import Waargonaut.Types.CommaSep.Elem (Comma (..), Elem (..),+ HasElem (..), parseComma,+ _ElemTrailingIso) -import Data.Witherable (Filterable (..), Witherable (..))+import Waargonaut.Types.CommaSep.Elems (Elems (..), HasElems (..),+ consElems,+ parseCommaSeparatedElems,+ unconsElems) -- $setup -- >>> :set -XOverloadedStrings -- >>> import Utils -- >>> import Waargonaut.Types.Json--- >>> import Control.Applicative (Applicative, pure)+-- >>> import Waargonaut.Types.Whitespace+-- >>> import Control.Monad (return) -- >>> import Data.Either (Either (..), isLeft) -- >>> import Waargonaut.Decode.Error (DecodeError)--- >>> import Text.Parser.Char (CharParsing, alphaNum)--- >>> import Waargonaut.Types.Whitespace (WS (..), Whitespace (..), parseWhitespace)+-- >>> import Data.Digit (HeXDigit)+-- >>> import Data.Char (Char)+-- >>> import Text.Parser.Char (alphaNum, char) -- >>> let charWS = ((,) <$> alphaNum <*> parseWhitespace) :: CharParsing f => f (Char, WS) ---- --- | Unary type to represent a comma.-data Comma = Comma- deriving (Eq, Show)---- | Isomorphism for 'Comma'.-_Comma :: Iso' Comma ()-_Comma = iso (\Comma -> ()) (const Comma)---- | Builder for UTF8 Comma-commaBuilder :: Builder-commaBuilder = TB.singleton ','-{-# INLINE commaBuilder #-}---- | Parse a single comma (,)-parseComma :: CharParsing f => f Comma-parseComma = Comma <$ char ','-{-# INLINE parseComma #-}----- | Data type to represent a single element in a 'CommaSeparated' list. Carries--- information about it's own trailing whitespace. Denoted by the 'f'.-data Elem f ws a = Elem- { _elemVal :: a- , _elemTrailing :: f (Comma, ws)- }- deriving (Functor, Foldable, Traversable)--instance (Monoid ws, Applicative f) => Applicative (Elem f ws) where- pure a = Elem a (pure (Comma, mempty))- (Elem atob _) <*> (Elem a t') = Elem (atob a) t'--instance Functor f => Bifunctor (Elem f) where- bimap f g (Elem a t) = Elem (g a) (fmap (fmap f) t)--instance Foldable f => Bifoldable (Elem f) where- bifoldMap f g (Elem a t) = g a `mappend` foldMap (foldMap f) t--instance Traversable f => Bitraversable (Elem f) where- bitraverse f g (Elem a t) = Elem <$> g a <*> traverse (traverse f) t---- | Typeclass for things that contain a single 'Elem' structure.-class HasElem c f ws a | c -> f ws a where- elem :: Lens' c (Elem f ws a)- elemTrailing :: Lens' c (f (Comma, ws))- {-# INLINE elemTrailing #-}- elemVal :: Lens' c a- {-# INLINE elemVal #-}- elemTrailing = elem . elemTrailing- elemVal = elem . elemVal--instance HasElem (Elem f ws a) f ws a where- {-# INLINE elemTrailing #-}- {-# INLINE elemVal #-}- elem = id- elemTrailing f (Elem x1 x2) = Elem x1 <$> f x2- elemVal f (Elem x1 x2) = (`Elem` x2) <$> f x1--instance (Show1 f, Show ws, Show a) => Show (Elem f ws a) where- showsPrec _ (Elem v t) =- showString "Elem {_elemVal = " . shows v .- showString ", _elemTrailing = " . showsPrec1 0 t . showString "}"--instance (Eq1 f, Eq ws, Eq a) => Eq (Elem f ws a) where- Elem v1 t1 == Elem v2 t2 = v1 == v2 && eq1 t1 t2--floopId :: Monoid ws => Iso' (Identity (Comma,ws)) (Maybe (Comma,ws))-floopId = iso (Just . runIdentity) (pure . fromMaybe (Comma, mempty))--_ElemTrailingIso- :: ( Monoid ws- , Monoid ws'- )- => Iso (Elem Identity ws a) (Elem Identity ws' a') (Elem Maybe ws a) (Elem Maybe ws' a')-_ElemTrailingIso = iso- (\(Elem a t) -> Elem a (t ^. floopId))- (\(Elem a t) -> Elem a (t ^. from floopId))---- | This type represents a non-empty list of elements, enforcing that the any--- element but the last must be followed by a trailing comma and supporting option--- of a final trailing comma.-data Elems ws a = Elems- { _elemsElems :: Vector (Elem Identity ws a)- , _elemsLast :: Elem Maybe ws a- }- deriving (Eq, Show, Functor, Foldable, Traversable)--instance Bifunctor Elems where- bimap f g (Elems es el) = Elems (fmap (bimap f g) es) (bimap f g el)--instance Bifoldable Elems where- bifoldMap f g (Elems es el) = foldMap (bifoldMap f g) es `mappend` bifoldMap f g el--instance Bitraversable Elems where- bitraverse f g (Elems es el) = Elems <$> traverse (bitraverse f g) es <*> bitraverse f g el---- | Typeclass for things that contain an 'Elems' structure.-class HasElems c ws a | c -> ws a where- elems :: Lens' c (Elems ws a)- elemsElems :: Lens' c (Vector (Elem Identity ws a))- {-# INLINE elemsElems #-}- elemsLast :: Lens' c (Elem Maybe ws a)- {-# INLINE elemsLast #-}- elemsElems = elems . elemsElems- elemsLast = elems . elemsLast--instance HasElems (Elems ws a) ws a where- {-# INLINE elemsElems #-}- {-# INLINE elemsLast #-}- elems = id- elemsElems f (Elems x1 x2) = fmap (`Elems` x2) (f x1)- elemsLast f (Elems x1 x2) = fmap (Elems x1) (f x2)--instance Monoid ws => Applicative (Elems ws) where- pure a = Elems mempty (pure a)- Elems atobs atob <*> Elems as a = Elems (liftA2 (<*>) atobs as) (atob <*> a)--instance Monoid ws => Semigroup (Elems ws a) where- (<>) (Elems as alast) (Elems bs blast) =- Elems (snoc as (alast ^. from _ElemTrailingIso) <> bs) blast- -- | This type is our possibly empty comma-separated list of values. It carries -- information about any leading whitespace before the first element, as well as a -- the rest of the elements in an 'Elems' type.@@ -236,7 +117,9 @@ -- | By ignoring whitespace we're able to write a 'Cons' instance. instance Monoid ws => Cons (CommaSeparated ws a) (CommaSeparated ws a) a a where- _Cons = prism (\(a,cs) -> consCommaSep ((Comma,mempty), a) cs) (\c -> note c . over (mapped . _1) (^. _2) $ unconsCommaSep c)+ _Cons = prism+ (\(a,cs) -> consCommaSep ((Comma,mempty), a) cs)+ (\c -> note c . over (mapped . _1) (^. _2) $ unconsCommaSep c) {-# INLINE _Cons #-} instance Monoid ws => Snoc (CommaSeparated ws a) (CommaSeparated ws a) a a where@@ -260,18 +143,6 @@ & elemsElems .~ newEs & elemsLast .~ newL ^. _ElemTrailingIso -consElems :: Monoid ws => ((Comma,ws), a) -> Elems ws a -> Elems ws a-consElems (ews,a) e = e & elemsElems %~ cons (Elem a (Identity ews))-{-# INLINE consElems #-}--unconsElems :: Monoid ws => Elems ws a -> ((Maybe (Comma,ws), a), Maybe (Elems ws a))-unconsElems e = maybe (e', Nothing) (\(em, ems) -> (idT em, Just $ e & elemsElems .~ ems)) es'- where- es' = e ^? elemsElems . _Cons- e' = (e ^. elemsLast . elemTrailing, e ^. elemsLast . elemVal)- idT x = (x ^. elemTrailing . to (Just . runIdentity), x ^. elemVal)-{-# INLINE unconsElems #-}- instance (Monoid ws, Semigroup ws) => Semigroup (CommaSeparated ws a) where (CommaSeparated wsA a) <> (CommaSeparated wsB b) = CommaSeparated (wsA <> wsB) (a <> b) @@ -327,6 +198,7 @@ -- | Convert a list of 'a' to a 'CommaSeparated' list, with no whitespace. fromList :: (Monoid ws, Semigroup ws) => [a] -> CommaSeparated ws a fromList = foldr cons mempty+{-# INLINE fromList #-} -- | Convert a 'CommaSeparated' of 'a' to @[a]@, discarding whitespace. toList :: CommaSeparated ws a -> [a]@@ -334,96 +206,22 @@ g e = snoc (e ^.. elemsElems . traverse . elemVal) (e ^. elemsLast . elemVal) {-# INLINE toList #-} --- | Parse an optional comma and its trailing whitespace.------ >>> testparse (parseCommaTrailingMaybe parseWhitespace) ", "--- Right (Just (Comma,WS [Space]))------ >>> testparse (parseCommaTrailingMaybe parseWhitespace) " , "--- Right Nothing------ >>> testparse (parseCommaTrailingMaybe parseWhitespace) ",, "--- Right (Just (Comma,WS []))----parseCommaTrailingMaybe- :: CharParsing f- => f ws- -> f (Maybe (Comma, ws))-parseCommaTrailingMaybe =- C.optional . liftA2 (,) parseComma---- | Builder for a comma and trailing whitespace combination.-commaTrailingBuilder- :: Foldable f- => (ws -> Builder)- -> f (Comma, ws)- -> Builder-commaTrailingBuilder wsB =- foldMap ((commaBuilder <>) . wsB . snd)---- | Using the given builders for the whitespace and elements ('a'), create a--- builder for a 'CommaSeparated'.-commaSeparatedBuilder- :: forall ws a. Char- -> Char- -> (ws -> Builder)- -> (a -> Builder)- -> CommaSeparated ws a- -> Builder-commaSeparatedBuilder op fin wsB aB (CommaSeparated lws sepElems) =- TB.singleton op <> wsB lws <> maybe mempty buildElems sepElems <> TB.singleton fin- where- elemBuilder- :: Foldable f- => Elem f ws a -> Builder- elemBuilder (Elem e eTrailing) =- aB e <> commaTrailingBuilder wsB eTrailing-- buildElems (Elems es elst) =- foldMap elemBuilder es <> elemBuilder elst---- | Parse the elements of a 'CommaSeparated' list, handling the optional trailing comma and its whitespace.------ >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b, c, d"--- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Nothing}})------ >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b,c,d, "--- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})------ >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "d, "--- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})------ >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d , "--- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = ('d',WS [Space]), _elemTrailing = Just (Comma,WS [Space])}})------ >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d\n, e, "--- Right (Elems {_elemsElems = [Elem {_elemVal = ('d',WS [NewLine]), _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = ('e',WS []), _elemTrailing = Just (Comma,WS [Space,Space])}})----parseCommaSeparatedElems- :: ( Monad f- , CharParsing f- )- => f ws- -> f a- -> f (Elems ws a)-parseCommaSeparatedElems ws a = do- hd <- a- sep <- parseCommaTrailingMaybe ws- maybe (pure $ Elems mempty (Elem hd sep)) (go mempty . (hd,)) sep- where- idElem e = Elem e . Identity-- fin cels lj sp =- pure $ Elems cels (Elem lj sp)-- go commaElems (lastJ, lastSep) = do- mJ <- C.optional a- case mJ of- Nothing -> fin commaElems lastJ (Just lastSep)- Just j -> do- msep <- parseCommaTrailingMaybe ws- let commaElems' = snoc commaElems $ idElem lastJ lastSep- maybe (fin commaElems' j Nothing) (go commaElems' . (j,)) msep+fromCommaSep+ :: Traversal' j (CommaSeparated ws x)+ -> v+ -> (Elems ws a -> v)+ -> (x -> Maybe a)+ -> j+ -> Either j v+fromCommaSep _HasCS empty builder decoder j =+ case preview (_HasCS . _CommaSeparated . _2) j of+ Nothing -> Left j -- Json input is not the write structure+ Just Nothing -> Right empty -- Json input is the right structure but empty so return empty+ Just (Just els) -> maybe+ (Left j) -- We've had a conversion failure+ (Right . builder) -- Try to lazily fold our values into the return type+ $ traverse decoder els -- Try to decode the values+{-# INLINE fromCommaSep #-} -- | Parse a 'CommaSeparated' data structure. --
+ src/Waargonaut/Types/CommaSep/Elem.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+module Waargonaut.Types.CommaSep.Elem+ (+ -- * Types+ Elem (..)+ , HasElem (..)+ , Comma (Comma)++ , _ElemTrailingIso++ -- * Parse+ , parseComma+ , parseCommaTrailingMaybe+ ) where++import Prelude (Eq, Show (showsPrec), showString,+ shows, (&&), (==))++import Control.Applicative (Applicative (..), liftA2, pure, (<*>))+import Control.Category (id, (.))++import Control.Lens (Iso, Iso', Lens', from, iso, (^.))++import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Foldable (Foldable, foldMap)+import Data.Functor (Functor, fmap, (<$), (<$>))+import Data.Functor.Classes (Eq1, Show1, eq1, showsPrec1)+import Data.Maybe (Maybe (..), fromMaybe)+import Data.Monoid (Monoid (..), mempty)+import Data.Traversable (Traversable, traverse)++import Data.Functor.Identity (Identity (..))++import Text.Parser.Char (CharParsing)+import qualified Text.Parser.Char as C+import qualified Text.Parser.Combinators as C++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Utils+-- >>> import Waargonaut.Types.Json+-- >>> import Waargonaut.Types.Whitespace+-- >>> import Data.Either (Either (..))+--++-- | Unary type to represent a comma.+data Comma = Comma+ deriving (Eq, Show)++-- | Parse a single comma (,)+parseComma :: CharParsing f => f Comma+parseComma = Comma <$ C.char ','+{-# INLINE parseComma #-}++-- | Parse an optional comma and its trailing whitespace.+--+-- >>> testparse (parseCommaTrailingMaybe parseWhitespace) ", "+-- Right (Just (Comma,WS [Space]))+--+-- >>> testparse (parseCommaTrailingMaybe parseWhitespace) " , "+-- Right Nothing+--+-- >>> testparse (parseCommaTrailingMaybe parseWhitespace) ",, "+-- Right (Just (Comma,WS []))+--+parseCommaTrailingMaybe+ :: CharParsing f+ => f ws+ -> f (Maybe (Comma, ws))+parseCommaTrailingMaybe =+ C.optional . liftA2 (,) parseComma++-- | Data type to represent a single element in a 'CommaSeparated' list. Carries+-- information about it's own trailing whitespace. Denoted by the 'f'.+data Elem f ws a = Elem+ { _elemVal :: a+ , _elemTrailing :: f (Comma, ws)+ }+ deriving (Functor, Foldable, Traversable)++instance (Monoid ws, Applicative f) => Applicative (Elem f ws) where+ pure a = Elem a (pure (Comma, mempty))+ (Elem atob _) <*> (Elem a t') = Elem (atob a) t'++instance Functor f => Bifunctor (Elem f) where+ bimap f g (Elem a t) = Elem (g a) (fmap (fmap f) t)++instance Foldable f => Bifoldable (Elem f) where+ bifoldMap f g (Elem a t) = g a `mappend` foldMap (foldMap f) t++instance Traversable f => Bitraversable (Elem f) where+ bitraverse f g (Elem a t) = Elem <$> g a <*> traverse (traverse f) t++-- | Typeclass for things that contain a single 'Elem' structure.+class HasElem c f ws a | c -> f ws a where+ elem :: Lens' c (Elem f ws a)+ elemTrailing :: Lens' c (f (Comma, ws))+ {-# INLINE elemTrailing #-}+ elemVal :: Lens' c a+ {-# INLINE elemVal #-}+ elemTrailing = elem . elemTrailing+ elemVal = elem . elemVal++instance HasElem (Elem f ws a) f ws a where+ {-# INLINE elemTrailing #-}+ {-# INLINE elemVal #-}+ elem = id+ elemTrailing f (Elem x1 x2) = Elem x1 <$> f x2+ elemVal f (Elem x1 x2) = (`Elem` x2) <$> f x1++instance (Show1 f, Show ws, Show a) => Show (Elem f ws a) where+ showsPrec _ (Elem v t) =+ showString "Elem {_elemVal = " . shows v .+ showString ", _elemTrailing = " . showsPrec1 0 t . showString "}"++instance (Eq1 f, Eq ws, Eq a) => Eq (Elem f ws a) where+ Elem v1 t1 == Elem v2 t2 = v1 == v2 && eq1 t1 t2++floopId :: Monoid ws => Iso' (Identity (Comma,ws)) (Maybe (Comma,ws))+floopId = iso (Just . runIdentity) (pure . fromMaybe (Comma, mempty))++_ElemTrailingIso+ :: ( Monoid ws+ , Monoid ws'+ )+ => Iso (Elem Identity ws a) (Elem Identity ws' a') (Elem Maybe ws a) (Elem Maybe ws' a')+_ElemTrailingIso = iso+ (\(Elem a t) -> Elem a (t ^. floopId))+ (\(Elem a t) -> Elem a (t ^. from floopId))
+ src/Waargonaut/Types/CommaSep/Elems.hs view
@@ -0,0 +1,166 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TupleSections #-}+module Waargonaut.Types.CommaSep.Elems+ (+ -- * Types+ Elems (..)+ , HasElems (..)++ -- * Parse+ , parseCommaSeparatedElems++ -- * Functions+ , consElems+ , unconsElems+ ) where++import Prelude (Eq, Show)++import Control.Applicative (Applicative (..), liftA2, pure,+ (<*>))+import Control.Category (id, (.))+import Control.Monad (Monad)++import Control.Lens (Lens', cons, from, snoc, to,+ (%~), (.~), (^.), (^?), _Cons)++import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Foldable (Foldable, foldMap)+import Data.Function (($), (&))+import Data.Functor (Functor, fmap, (<$>))+import Data.Functor.Identity (Identity (..))+import Data.Maybe (Maybe (..), maybe)+import Data.Monoid (Monoid (..), mempty)+import Data.Semigroup (Semigroup ((<>)))+import Data.Traversable (Traversable, traverse)++import Data.Vector (Vector)++import Text.Parser.Char (CharParsing)+import qualified Text.Parser.Combinators as C++import Waargonaut.Types.CommaSep.Elem (Comma, Elem (..), HasElem (..),+ parseCommaTrailingMaybe,+ _ElemTrailingIso)+-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Utils+-- >>> import Waargonaut.Types.Json+-- >>> import Waargonaut.Types.Whitespace+-- >>> import Control.Monad (return)+-- >>> import Data.Either (Either (..), isLeft)+-- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Data.Digit (HeXDigit)+-- >>> import Text.Parser.Char (alphaNum)+-- >>> import Data.Char (Char)+-- >>> let charWS = ((,) <$> alphaNum <*> parseWhitespace) :: CharParsing f => f (Char, WS)+----++-- | This type represents a non-empty list of elements, enforcing that the any+-- element but the last must be followed by a trailing comma and supporting option+-- of a final trailing comma.+data Elems ws a = Elems+ { _elemsElems :: Vector (Elem Identity ws a)+ , _elemsLast :: Elem Maybe ws a+ }+ deriving (Eq, Show, Functor, Foldable, Traversable)++instance Bifunctor Elems where+ bimap f g (Elems es el) = Elems (fmap (bimap f g) es) (bimap f g el)++instance Bifoldable Elems where+ bifoldMap f g (Elems es el) = foldMap (bifoldMap f g) es `mappend` bifoldMap f g el++instance Bitraversable Elems where+ bitraverse f g (Elems es el) = Elems+ <$> traverse (bitraverse f g) es+ <*> bitraverse f g el++-- | Typeclass for things that contain an 'Elems' structure.+class HasElems c ws a | c -> ws a where+ elems :: Lens' c (Elems ws a)+ elemsElems :: Lens' c (Vector (Elem Identity ws a))+ {-# INLINE elemsElems #-}+ elemsLast :: Lens' c (Elem Maybe ws a)+ {-# INLINE elemsLast #-}+ elemsElems = elems . elemsElems+ elemsLast = elems . elemsLast++instance HasElems (Elems ws a) ws a where+ {-# INLINE elemsElems #-}+ {-# INLINE elemsLast #-}+ elems = id+ elemsElems f (Elems x1 x2) = fmap (`Elems` x2) (f x1)+ elemsLast f (Elems x1 x2) = fmap (Elems x1) (f x2)++instance Monoid ws => Applicative (Elems ws) where+ pure a = Elems mempty (pure a)+ Elems atobs atob <*> Elems as a = Elems (liftA2 (<*>) atobs as) (atob <*> a)++instance Monoid ws => Semigroup (Elems ws a) where+ (<>) (Elems as alast) (Elems bs blast) =+ Elems (snoc as (alast ^. from _ElemTrailingIso) <> bs) blast++consElems :: Monoid ws => ((Comma,ws), a) -> Elems ws a -> Elems ws a+consElems (ews,a) e = e & elemsElems %~ cons (Elem a (Identity ews))+{-# INLINE consElems #-}++unconsElems :: Monoid ws => Elems ws a -> ((Maybe (Comma,ws), a), Maybe (Elems ws a))+unconsElems e = maybe (e', Nothing) (\(em, ems) -> (idT em, Just $ e & elemsElems .~ ems)) es'+ where+ es' = e ^? elemsElems . _Cons+ e' = (e ^. elemsLast . elemTrailing, e ^. elemsLast . elemVal)+ idT x = (x ^. elemTrailing . to (Just . runIdentity), x ^. elemVal)+{-# INLINE unconsElems #-}++-- | Parse the elements of a 'CommaSeparated' list, handling the optional trailing comma and its whitespace.+--+-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b, c, d"+-- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Nothing}})+--+-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b,c,d, "+-- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})+--+-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "d, "+-- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})+--+-- >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d , "+-- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = ('d',WS [Space]), _elemTrailing = Just (Comma,WS [Space])}})+--+-- >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d\n, e, "+-- Right (Elems {_elemsElems = [Elem {_elemVal = ('d',WS [NewLine]), _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = ('e',WS []), _elemTrailing = Just (Comma,WS [Space,Space])}})+--+parseCommaSeparatedElems+ :: ( Monad f+ , CharParsing f+ )+ => f ws+ -> f a+ -> f (Elems ws a)+parseCommaSeparatedElems ws a = do+ hd <- a+ sep <- parseCommaTrailingMaybe ws+ maybe (pure $ Elems mempty (Elem hd sep)) (go mempty . (hd,)) sep+ where+ idElem e = Elem e . Identity++ fin cels lj sp =+ pure $ Elems cels (Elem lj sp)++ go commaElems (lastJ, lastSep) = do+ mJ <- C.optional a+ case mJ of+ Nothing -> fin commaElems lastJ (Just lastSep)+ Just j -> do+ msep <- parseCommaTrailingMaybe ws+ let commaElems' = snoc commaElems $ idElem lastJ lastSep+ maybe (fin commaElems' j Nothing) (go commaElems' . (j,)) msep
src/Waargonaut/Types/JArray.hs view
@@ -12,9 +12,8 @@ -- * Types JArray (..) - -- * Parser / Builder+ -- * Parser , parseJArray- , jArrayBuilder ) where import Prelude (Eq, Show, Int)@@ -38,12 +37,9 @@ import Data.Semigroup (Semigroup (..)) import Data.Traversable (Traversable) -import Data.Text.Lazy.Builder (Builder)- import Text.Parser.Char (CharParsing, char) import Waargonaut.Types.CommaSep (CommaSeparated,- commaSeparatedBuilder, parseCommaSeparated) -- $setup@@ -117,12 +113,3 @@ -> f (JArray ws a) parseJArray ws a = JArray <$> parseCommaSeparated (char '[') (char ']') ws a---- | Using the given builders, build a 'JArray'.-jArrayBuilder- :: (ws -> Builder)- -> ((ws -> Builder) -> a -> Builder)- -> JArray ws a- -> Builder-jArrayBuilder ws a (JArray cs) =- commaSeparatedBuilder '[' ']' ws (a ws) cs
src/Waargonaut/Types/JChar.hs view
@@ -4,7 +4,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-}@@ -13,236 +12,71 @@ module Waargonaut.Types.JChar ( -- * Types- HexDigit4 (..)- , HasHexDigit4 (..)- , JChar (..)+ JChar (..) , AsJChar (..) , HasJChar (..)- , JCharEscaped (..)- , AsJCharEscaped (..)- , JCharUnescaped (..)- , AsJCharUnescaped (..) - -- * Parser / Builder+ -- * Parser , parseJChar- , parseJCharEscaped- , parseJCharUnescaped- , jCharBuilderWith- , jCharBuilderTextL- , jCharBuilderByteStringL - , jCharToChar- -- * Conversion , utf8CharToJChar , jCharToUtf8Char+ , jCharToChar+ , charToJChar ) where -import Prelude (Char, Eq, Int, Ord, Show,- otherwise, quotRem, (&&), (*),- (+), (-), (/=), (<=), (==), (>=))--import Control.Category (id, (.))-import Control.Lens (Lens', Prism', Rewrapped,- Wrapped (..), failing, has, iso,- prism, prism', to, ( # ), (^?),- _Just)--import Control.Applicative (pure, (*>), (<$>), (<*>), (<|>))-import Control.Monad ((=<<))+import Prelude (Char, Eq, Ord, Show,+ otherwise, (/=)) -import Control.Error.Util (note)+import Control.Category (id, (.))+import Control.Lens (Lens', Prism', preview,+ prism, review) -import Data.Bits ((.&.))+import Control.Applicative ((<$>), (<|>)) -import Data.Char (chr, ord)-import Data.Either (Either (..))-import Data.Foldable (Foldable, any, asum, foldMap,- foldl)-import Data.Function (const, ($))-import Data.Functor (Functor)-import Data.Maybe (Maybe (..), fromMaybe)-import Data.Monoid (Monoid)-import Data.Semigroup (Semigroup, (<>))-import Data.Traversable (Traversable, traverse)+import Data.Bits ((.&.))+import Data.Char (ord)+import Data.Either (Either (..))+import Data.Foldable (Foldable, asum)+import Data.Function (($))+import Data.Functor (Functor)+import Data.Maybe (Maybe (..), fromMaybe)+import Data.Traversable (Traversable) -import qualified Data.Text.Internal as Text+import qualified Data.Text.Internal as Text -import Data.Digit (HeXDigit, HeXaDeCiMaL)-import qualified Data.Digit as D+import Data.Digit (HeXDigit, HeXaDeCiMaL)+import qualified Data.Digit as D -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB+import Text.Parser.Char (CharParsing) -import qualified Data.ByteString.Lazy.Builder as BB+import Waargonaut.Types.JChar.HexDigit4 (HexDigit4 (..)) -import Waargonaut.Types.Whitespace (Whitespace (..),- escapedWhitespaceChar,- unescapedWhitespaceChar,- _WhitespaceChar)+import Waargonaut.Types.JChar.Escaped (AsEscaped (..), Escaped (..),+ charToEscaped, escapedToChar,+ parseEscaped) -import Text.Parser.Char (CharParsing, char, satisfy)+import Waargonaut.Types.JChar.Unescaped (AsUnescaped (..), Unescaped,+ parseUnescaped) -- $setup -- >>> :set -XOverloadedStrings--- >>> import Control.Monad (return)+-- >>> import Data.Function (($)) -- >>> import Data.Either(Either (..), isLeft) -- >>> import Data.Digit (HeXDigit(..))--- >>> import qualified Data.Digit as D--- >>> import Waargonaut.Decode.Error (DecodeError) -- >>> import Utils+-- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Waargonaut.Types.Whitespace+-- >>> import Waargonaut.Types.JChar.Unescaped+-- >>> import Waargonaut.Types.JChar.Escaped+-- >>> import Waargonaut.Types.JChar ---- --- | JSON Characters may be single escaped UTF16 "\uab34".-data HexDigit4 d =- HexDigit4 d d d d- deriving (Eq, Show, Ord, Functor, Foldable, Traversable)---- | Typeclass for things that contain a 'HexDigit4'.-class HasHexDigit4 c d | c -> d where- hexDigit4 :: Lens' c (HexDigit4 d)--instance HasHexDigit4 (HexDigit4 d) d where- hexDigit4 = id---- | Type to specify that this character is unescaped and may be represented--- using a normal Haskell 'Char'.-newtype JCharUnescaped =- JCharUnescaped Char- deriving (Eq, Ord, Show)--instance JCharUnescaped ~ t => Rewrapped JCharUnescaped t-instance Wrapped JCharUnescaped where- type Unwrapped JCharUnescaped = Char- _Wrapped' = iso (\ (JCharUnescaped x) -> x) JCharUnescaped---- | Typeclass for things that may used as an unescaped JChar.-class AsJCharUnescaped a where- _JCharUnescaped :: Prism' a JCharUnescaped--instance AsJCharUnescaped JCharUnescaped where- _JCharUnescaped = id--instance AsJCharUnescaped Char where- _JCharUnescaped = prism'- (\(JCharUnescaped c) -> c)- (\c -> if any ($ c) excluded then Nothing- else Just (JCharUnescaped c)- )- where- excluded =- [ (== '\NUL')- , (== '"')- , (== '\\')- , \x -> x >= '\x00' && x <= '\x1f'- ]---- | Things that may be escaped in a JSON string.-data JCharEscaped digit- = QuotationMark- | ReverseSolidus- | Solidus- | Backspace- | WhiteSpace Whitespace- | Hex ( HexDigit4 digit )- deriving (Eq, Ord, Show, Functor, Foldable, Traversable)---- | Typeclass for things that may be used as an escaped JChar.-class AsJCharEscaped r digit | r -> digit where- _JCharEscaped :: Prism' r (JCharEscaped digit)- _QuotationMark :: Prism' r ()- _ReverseSolidus :: Prism' r ()- _Solidus :: Prism' r ()- _Backspace :: Prism' r ()- _WhiteSpace :: Prism' r Whitespace- _Hex :: Prism' r (HexDigit4 digit)-- _QuotationMark = _JCharEscaped . _QuotationMark- _ReverseSolidus = _JCharEscaped . _ReverseSolidus- _Solidus = _JCharEscaped . _Solidus- _Backspace = _JCharEscaped . _Backspace- _WhiteSpace = _JCharEscaped . _WhiteSpace- _Hex = _JCharEscaped . _Hex--instance AsJCharEscaped (JCharEscaped digit) digit where- _JCharEscaped = id- _QuotationMark = prism (const QuotationMark)- (\ x -> case x of- QuotationMark -> Right ()- _ -> Left x- )- _ReverseSolidus = prism (const ReverseSolidus)- (\ x -> case x of- ReverseSolidus -> Right ()- _ -> Left x- )- _Solidus = prism (const Solidus)- (\ x -> case x of- Solidus -> Right ()- _ -> Left x- )- _Backspace = prism (const Backspace)- (\ x -> case x of- Backspace -> Right ()- _ -> Left x- )- _WhiteSpace = prism WhiteSpace- (\ x -> case x of- WhiteSpace y1 -> Right y1- _ -> Left x- )- _Hex = prism Hex- (\ x -> case x of- Hex y1 -> Right y1- _ -> Left x- )---- | Convert a given 'HexDigit4' to a Haskell 'Char'.-hexDigit4ToChar- :: HeXaDeCiMaL digit- => HexDigit4 digit- -> Char-hexDigit4ToChar (HexDigit4 a b c d) =- chr (foldl (\acc x -> 16 * acc + (D.integralHexadecimal # x)) 0 [a,b,c,d])--sandblast :: Char -> Maybe (HexDigit4 HeXDigit)-sandblast x = if x >= '\x0' && x <= '\xffff'- then shuriken =<< traverse (^? D.integralHexadecimal) (lavawave 4 [] (bile (ord x)))- else Nothing- where- shuriken (a:b:c:d:_) = Just (HexDigit4 a b c d)- shuriken _ = Nothing-- bile n = quotRem n 16-- lavawave :: Int -> [Int] -> (Int,Int) -> [Int]- lavawave 0 acc _ = acc- lavawave n acc (0,0) = lavawave (n - 1) (0:acc) (0,0)- lavawave n acc (q,r) = lavawave (n - 1) (r:acc) (bile q)- {-# INLINE lavawave #-}-{-# INLINE sandblast #-}--instance AsJCharEscaped Char HeXDigit where- _JCharEscaped = prism- (\case- QuotationMark -> '"'- ReverseSolidus -> '\\'- Solidus -> '/'- Backspace -> '\b'- WhiteSpace wc -> escapedWhitespaceChar wc- Hex hd -> hexDigit4ToChar hd- )- (\c -> case c of- '"' -> Right QuotationMark- '\\' -> Right ReverseSolidus- '/' -> Right Solidus- '\b' -> Right Backspace- _ -> note c $ c ^? failing (_WhitespaceChar . to WhiteSpace) (to sandblast . _Just . to Hex)- ) -- | A JChar may be unescaped or escaped. data JChar digit- = EscapedJChar ( JCharEscaped digit )- | UnescapedJChar JCharUnescaped+ = EscapedJChar ( Escaped digit )+ | UnescapedJChar Unescaped deriving (Eq, Ord, Show, Functor, Foldable, Traversable) -- | Typeclass for things that have a 'JChar'.@@ -255,8 +89,8 @@ -- | Typeclass for things that be used as a 'JChar'. class AsJChar r digit | r -> digit where _JChar :: Prism' r (JChar digit)- _EscapedJChar :: Prism' r (JCharEscaped digit)- _UnescapedJChar :: Prism' r JCharUnescaped+ _EscapedJChar :: Prism' r (Escaped digit)+ _UnescapedJChar :: Prism' r Unescaped _EscapedJChar = _JChar . _EscapedJChar _UnescapedJChar = _JChar . _UnescapedJChar@@ -274,24 +108,24 @@ _ -> Left x ) -instance AsJCharEscaped (JChar digit) digit where- _JCharEscaped = _JChar . _JCharEscaped+instance AsEscaped (JChar digit) digit where+ _Escaped = _JChar . _Escaped -instance AsJCharUnescaped (JChar digit) where- _JCharUnescaped = _JChar . _JCharUnescaped+instance AsUnescaped (JChar digit) where+ _Unescaped = _JChar . _Unescaped -instance AsJChar Char HeXDigit where- _JChar = prism- (\case- UnescapedJChar jcu -> _JCharUnescaped # jcu- EscapedJChar jce -> _JCharEscaped # jce- )- (\c -> note c $ c ^? failing- (_JCharUnescaped . to UnescapedJChar)- (_JCharEscaped . to EscapedJChar)- )+-- instance AsJChar Char HeXDigit where+-- Don't implement this, it's not a lawful prism. --- | Helper to determine if the given 'Char' is an acceptable utf8 value.+jCharToChar :: JChar HeXDigit -> Char+jCharToChar (UnescapedJChar uejc) = review _Unescaped uejc+jCharToChar (EscapedJChar ejc) = escapedToChar ejc++charToJChar :: Char -> Maybe (JChar HeXDigit)+charToJChar c =+ (UnescapedJChar <$> preview _Unescaped c) <|>+ (EscapedJChar <$> charToEscaped c)+ utf8SafeChar :: Char -> Maybe Char utf8SafeChar c | ord c .&. 0x1ff800 /= 0xd800 = Just c | otherwise = Nothing@@ -302,116 +136,16 @@ -- Refer to <https://hackage.haskell.org/package/text/docs/Data-Text.html#g:2 'Text'> documentation for more info. -- utf8CharToJChar :: Char -> JChar HeXDigit-utf8CharToJChar c = fromMaybe scalarReplacement (Text.safe c ^? _JChar)+utf8CharToJChar c = fromMaybe scalarReplacement (charToJChar $ Text.safe c) where scalarReplacement = EscapedJChar (Hex (HexDigit4 D.xf D.xf D.xf D.xd)) {-# INLINE utf8CharToJChar #-} --- | Try to convert a 'JChar' to a Haskell 'Char'.+-- | Try to convert a 'JChar' to a 'Text' safe 'Char' value. Refer to the link for more info:+-- https://hackage.haskell.org/package/text-1.2.3.0/docs/Data-Text-Internal.html#v:safe jCharToUtf8Char :: JChar HeXDigit -> Maybe Char-jCharToUtf8Char jc = utf8SafeChar (_JChar # jc)+jCharToUtf8Char = utf8SafeChar . jCharToChar {-# INLINE jCharToUtf8Char #-} --- | Parse a single 'HexDigit4'.------ >>> testparse parseHexDigit4 "1234" :: Either DecodeError (HexDigit4 HeXDigit)--- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigit3 HeXDigit4)------ >>> testparse parseHexDigit4 "12aF" :: Either DecodeError (HexDigit4 HeXDigit)--- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)------ >>> testparse parseHexDigit4 "aBcD" :: Either DecodeError (HexDigit4 HeXDigit)--- Right (HexDigit4 HeXDigita HeXDigitB HeXDigitc HeXDigitD)------ >>> testparsetheneof parseHexDigit4 "12aF" :: Either DecodeError (HexDigit4 HeXDigit)--- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)------ >>> testparsethennoteof parseHexDigit4 "12aFx" :: Either DecodeError (HexDigit4 HeXDigit)--- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)-parseHexDigit4 ::- ( CharParsing f, HeXaDeCiMaL digit ) =>- f ( HexDigit4 digit )-parseHexDigit4 = HexDigit4- <$> D.parseHeXaDeCiMaL- <*> D.parseHeXaDeCiMaL- <*> D.parseHeXaDeCiMaL- <*> D.parseHeXaDeCiMaL---- | Parse an unescaped JSON character.------ >>> testparse parseJCharUnescaped "a"--- Right (JCharUnescaped 'a')------ >>> testparse parseJCharUnescaped "\8728"--- Right (JCharUnescaped '\8728')------ >>> testparsetheneof parseJCharUnescaped "a"--- Right (JCharUnescaped 'a')------ >>> testparsethennoteof parseJCharUnescaped "ax"--- Right (JCharUnescaped 'a')-parseJCharUnescaped ::- CharParsing f =>- f JCharUnescaped-parseJCharUnescaped =- JCharUnescaped <$> satisfy (has _JCharUnescaped)---- | Parse an escapted JSON character.------ >>> testparse parseJCharEscaped "\\\""--- Right QuotationMark------ >>> testparse parseJCharEscaped "\\\\"--- Right ReverseSolidus------ >>> testparse parseJCharEscaped "\\/"--- Right Solidus------ >>> testparse parseJCharEscaped "\\b"--- Right Backspace------ >>> testparse parseJCharEscaped "\\f"--- Right (WhiteSpace LineFeed)------ >>> testparse parseJCharEscaped "\\n"--- Right (WhiteSpace NewLine)------ >>> testparse parseJCharEscaped "\\r"--- Right (WhiteSpace CarriageReturn)------ >>> testparse parseJCharEscaped "\\t"--- Right (WhiteSpace HorizontalTab)------ >>> testparse parseJCharEscaped "\\u1234" :: Either DecodeError (JCharEscaped HeXDigit)--- Right (Hex (HexDigit4 HeXDigit1 HeXDigit2 HeXDigit3 HeXDigit4))------ >>> testparsetheneof parseJCharEscaped "\\t"--- Right (WhiteSpace HorizontalTab)------ >>> testparsethennoteof parseJCharEscaped "\\tx"--- Right (WhiteSpace HorizontalTab)-parseJCharEscaped ::- (CharParsing f, HeXaDeCiMaL digit) =>- f ( JCharEscaped digit )-parseJCharEscaped =- let- z =- asum ((\(c, p) -> char c *> pure p) <$>- [- ('"' , QuotationMark)- , ('\\', ReverseSolidus)- , ('/' , Solidus)- , ('b' , Backspace)- , (' ' , WhiteSpace Space)- , ('f' , WhiteSpace LineFeed)- , ('n' , WhiteSpace NewLine)- , ('r' , WhiteSpace CarriageReturn)- , ('t' , WhiteSpace HorizontalTab)- ])- h =- Hex <$> (char 'u' *> parseHexDigit4)- in- char '\\' *> (z <|> h)- -- | Parse a JSON character. -- -- >>> testparse parseJChar "\\u1234" :: Either DecodeError (JChar HeXDigit)@@ -424,57 +158,14 @@ -- Right (EscapedJChar (WhiteSpace CarriageReturn)) -- -- >>> testparsetheneof parseJChar "a"--- Right (UnescapedJChar (JCharUnescaped 'a'))+-- Right (UnescapedJChar (Unescaped 'a')) -- -- >>> testparsethennoteof parseJChar "ax"--- Right (UnescapedJChar (JCharUnescaped 'a'))+-- Right (UnescapedJChar (Unescaped 'a')) parseJChar :: (CharParsing f, HeXaDeCiMaL digit) => f ( JChar digit ) parseJChar = asum- [ EscapedJChar <$> parseJCharEscaped- , UnescapedJChar <$> parseJCharUnescaped+ [ EscapedJChar <$> parseEscaped+ , UnescapedJChar <$> parseUnescaped ]---- | Convert a 'JChar' to a Haskell 'Char'.-jCharToChar- :: HeXaDeCiMaL digit- => JChar digit- -> Char-jCharToChar (UnescapedJChar (JCharUnescaped c)) = c-jCharToChar (EscapedJChar jca) = case jca of- QuotationMark -> '"'- ReverseSolidus -> '\\'- Solidus -> '/'- Backspace -> '\b'- (WhiteSpace ws) -> _WhiteSpace # ws- Hex hexDig4 -> hexDigit4ToChar hexDig4---- | Using the given function, return the builder for a single 'JChar'.-jCharBuilderWith- :: ( Monoid builder- , Semigroup builder- , HeXaDeCiMaL digit- )- => (Char -> builder)- -> JChar digit- -> builder-jCharBuilderWith f (UnescapedJChar (JCharUnescaped c)) = f c-jCharBuilderWith f (EscapedJChar jca) = f '\\' <> case jca of- QuotationMark -> f '"'- ReverseSolidus -> f '\\'- Solidus -> f '/'- Backspace -> f 'b'- (WhiteSpace ws) -> f (unescapedWhitespaceChar ws)- Hex (HexDigit4 a b c d) -> f 'u' <> foldMap hexChar [a,b,c,d]- where- hexChar =- f . (D.charHeXaDeCiMaL #)---- | Create a Lazy 'Text' 'Data.Text.Lazy.Builder' for the given 'JChar'.-jCharBuilderTextL :: HeXaDeCiMaL digit => JChar digit -> Builder-jCharBuilderTextL = jCharBuilderWith TB.singleton---- | Create a Lazy 'ByteString' 'Data.ByteString.Lazy.Builder' for a given 'JChar'-jCharBuilderByteStringL :: HeXaDeCiMaL digit => JChar digit -> BB.Builder-jCharBuilderByteStringL = jCharBuilderWith BB.charUtf8
+ src/Waargonaut/Types/JChar/Escaped.hs view
@@ -0,0 +1,198 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+-- | Types and functions for handling escaped characters in JSON.+module Waargonaut.Types.JChar.Escaped+ (+ -- * Types+ Escaped (..)+ , AsEscaped (..)++ -- * Parser+ , parseEscaped++ -- * Conversion+ , escapedToChar+ , charToEscaped+ ) where++import Prelude (Eq, Ord, Show)++import Control.Applicative (pure, (*>), (<|>))+import Control.Category (id, (.))++import Control.Lens (Prism', preview, prism, to,+ _Just)++import Data.Foldable (Foldable, asum)+import Data.Functor (Functor, (<$>))+import Data.Traversable (Traversable)++import Data.Function (const)++import Data.Char (Char)+import Data.Either (Either (..))+import Data.Maybe (Maybe (..))++import Data.Digit (HeXDigit, HeXaDeCiMaL)++import Text.Parser.Char (CharParsing, char)++import Waargonaut.Types.JChar.HexDigit4 (HexDigit4, charToHexDigit4,+ hexDigit4ToChar,+ parseHexDigit4)+import Waargonaut.Types.Whitespace (Whitespace (..),+ unescapedWhitespaceChar,+ _WhitespaceChar)++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Control.Monad (return)+-- >>> import Data.Either(Either (..), isLeft)+-- >>> import Data.Digit (HeXDigit(..))+-- >>> import qualified Data.Digit as D+-- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Utils+----++-- | Things that may be escaped in a JSON string.+data Escaped digit+ = QuotationMark+ | ReverseSolidus+ | Solidus+ | Backspace+ | WhiteSpace Whitespace+ | Hex ( HexDigit4 digit )+ deriving (Eq, Ord, Show, Functor, Foldable, Traversable)++-- | Typeclass for things that may be used as an escaped JChar.+class AsEscaped r digit | r -> digit where+ _Escaped :: Prism' r (Escaped digit)+ _QuotationMark :: Prism' r ()+ _ReverseSolidus :: Prism' r ()+ _Solidus :: Prism' r ()+ _Backspace :: Prism' r ()+ _WhiteSpace :: Prism' r Whitespace+ _Hex :: Prism' r (HexDigit4 digit)++ _QuotationMark = _Escaped . _QuotationMark+ _ReverseSolidus = _Escaped . _ReverseSolidus+ _Solidus = _Escaped . _Solidus+ _Backspace = _Escaped . _Backspace+ _WhiteSpace = _Escaped . _WhiteSpace+ _Hex = _Escaped . _Hex++instance AsEscaped (Escaped digit) digit where+ _Escaped = id+ _QuotationMark = prism (const QuotationMark)+ (\ x -> case x of+ QuotationMark -> Right ()+ _ -> Left x+ )+ _ReverseSolidus = prism (const ReverseSolidus)+ (\ x -> case x of+ ReverseSolidus -> Right ()+ _ -> Left x+ )+ _Solidus = prism (const Solidus)+ (\ x -> case x of+ Solidus -> Right ()+ _ -> Left x+ )+ _Backspace = prism (const Backspace)+ (\ x -> case x of+ Backspace -> Right ()+ _ -> Left x+ )+ _WhiteSpace = prism WhiteSpace+ (\ x -> case x of+ WhiteSpace y1 -> Right y1+ _ -> Left x+ )+ _Hex = prism Hex+ (\ x -> case x of+ Hex y1 -> Right y1+ _ -> Left x+ )++-- | Parse an escapted JSON character.+--+-- >>> testparse parseEscaped "\\\""+-- Right QuotationMark+--+-- >>> testparse parseEscaped "\\\\"+-- Right ReverseSolidus+--+-- >>> testparse parseEscaped "\\/"+-- Right Solidus+--+-- >>> testparse parseEscaped "\\b"+-- Right Backspace+--+-- >>> testparse parseEscaped "\\f"+-- Right (WhiteSpace LineFeed)+--+-- >>> testparse parseEscaped "\\n"+-- Right (WhiteSpace NewLine)+--+-- >>> testparse parseEscaped "\\r"+-- Right (WhiteSpace CarriageReturn)+--+-- >>> testparse parseEscaped "\\t"+-- Right (WhiteSpace HorizontalTab)+--+-- >>> testparse parseEscaped "\\u1234" :: Either DecodeError (Escaped HeXDigit)+-- Right (Hex (HexDigit4 HeXDigit1 HeXDigit2 HeXDigit3 HeXDigit4))+--+-- >>> testparsetheneof parseEscaped "\\t"+-- Right (WhiteSpace HorizontalTab)+--+-- >>> testparsethennoteof parseEscaped "\\tx"+-- Right (WhiteSpace HorizontalTab)+parseEscaped ::+ (CharParsing f, HeXaDeCiMaL digit) =>+ f ( Escaped digit )+parseEscaped =+ let+ z =+ asum ((\(c, p) -> char c *> pure p) <$>+ [+ ('"' , QuotationMark)+ , ('\\', ReverseSolidus)+ , ('/' , Solidus)+ , ('b' , Backspace)+ , (' ' , WhiteSpace Space)+ , ('f' , WhiteSpace LineFeed)+ , ('n' , WhiteSpace NewLine)+ , ('r' , WhiteSpace CarriageReturn)+ , ('t' , WhiteSpace HorizontalTab)+ ])+ h =+ Hex <$> (char 'u' *> parseHexDigit4)+ in+ char '\\' *> (z <|> h)++escapedToChar :: Escaped HeXDigit -> Char+escapedToChar = \case+ QuotationMark -> '"'+ ReverseSolidus -> '\\'+ Solidus -> '/'+ Backspace -> '\b'+ WhiteSpace wc -> unescapedWhitespaceChar wc+ Hex hd -> hexDigit4ToChar hd++charToEscaped :: Char -> Maybe (Escaped HeXDigit)+charToEscaped c = case c of+ '"' -> Just QuotationMark+ '\\' -> Just ReverseSolidus+ '/' -> Just Solidus+ '\b' -> Just Backspace+ _ -> preview asWhitespace c <|> preview asHex c+ where+ asWhitespace = _WhitespaceChar . to WhiteSpace+ asHex = to charToHexDigit4 . _Just . to Hex
+ src/Waargonaut/Types/JChar/HexDigit4.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+-- | Types and functions for handling \\u0000 values in JSON.+module Waargonaut.Types.JChar.HexDigit4+ (+ -- * Types+ HexDigit4 (..)+ , HasHexDigit4 (..)++ -- * Parse / Build+ , parseHexDigit4++ -- * Conversion+ , hexDigit4ToChar+ , charToHexDigit4+ ) where++import Prelude (Eq, Ord (..), Show, otherwise, (||))++import Control.Applicative ((<*>))+import Control.Category (id, (.))+import Control.Lens (Lens')+import Control.Monad ((=<<))++import Control.Error.Util (hush)++import Data.List.NonEmpty (NonEmpty ((:|)))++import Data.Foldable (Foldable)+import Data.Function (($))+import Data.Functor (Functor, fmap, (<$>))+import Data.Traversable (Traversable)++import Data.Char (Char, chr, ord)+import Data.Either (Either (..))+import Data.Maybe (Maybe (..))+import Text.Parser.Char (CharParsing)++import Data.Digit (HeXDigit, HeXaDeCiMaL)+import qualified Data.Digit as D++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Control.Monad (return)+-- >>> import Data.Either(Either (..), isLeft)+-- >>> import Data.Digit (HeXDigit(..))+-- >>> import qualified Data.Digit as D+-- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Utils+----++-- | JSON Characters may be single escaped UTF16 "\uab34".+data HexDigit4 d =+ HexDigit4 d d d d+ deriving (Eq, Show, Ord, Functor, Foldable, Traversable)++-- | Typeclass for things that contain a 'HexDigit4'.+class HasHexDigit4 c d | c -> d where+ hexDigit4 :: Lens' c (HexDigit4 d)++instance HasHexDigit4 (HexDigit4 d) d where+ hexDigit4 = id++hexHeX :: D.HexDigit -> D.HeXDigit+hexHeX = \case+ D.HexDigit0 -> D.HeXDigit0+ D.HexDigit1 -> D.HeXDigit1+ D.HexDigit2 -> D.HeXDigit2+ D.HexDigit3 -> D.HeXDigit3+ D.HexDigit4 -> D.HeXDigit4+ D.HexDigit5 -> D.HeXDigit5+ D.HexDigit6 -> D.HeXDigit6+ D.HexDigit7 -> D.HeXDigit7+ D.HexDigit8 -> D.HeXDigit8+ D.HexDigit9 -> D.HeXDigit9+ D.HexDigita -> D.HeXDigita+ D.HexDigitb -> D.HeXDigitb+ D.HexDigitc -> D.HeXDigitc+ D.HexDigitd -> D.HeXDigitd+ D.HexDigite -> D.HeXDigite+ D.HexDigitf -> D.HeXDigitf++-- | Convert a given 'HexDigit4' to a Haskell 'Char'.+hexDigit4ToChar :: HexDigit4 HeXDigit -> Char+hexDigit4ToChar (HexDigit4 a b c d) = chr (D._HeXDigitsIntegral (Right $ a :| [b,c,d]))++-- | Try to convert a Haskell 'Char' to a JSON acceptable character. NOTE: This+-- cannot preserve the upper or lower casing of any original 'Json' data structure+-- inputs that may have been used to create this 'Char'. Also the JSON RFC+-- specifies a "limited" range of @U+0000@ to @U+FFFF@ as permissible as a six+-- character sequence: @\u0000@.+charToHexDigit4 :: Char -> Maybe (HexDigit4 HeXDigit)+charToHexDigit4 x+ | x < '\x0' || x > '\xffff' = Nothing+ | otherwise = toHexDig . fmap hexHeX =<< hush (D.integralHexDigits (ord x))+ where+ z = D.x0++ toHexDig (a :| [b,c,d]) = Just (HexDigit4 a b c d)+ toHexDig ( b :| [c,d]) = Just (HexDigit4 z b c d)+ toHexDig ( c :| [d]) = Just (HexDigit4 z z c d)+ toHexDig ( d :| []) = Just (HexDigit4 z z z d)+ toHexDig _ = Nothing++{-# INLINE charToHexDigit4 #-}++-- | Parse a single 'HexDigit4'.+--+-- >>> testparse parseHexDigit4 "1234" :: Either DecodeError (HexDigit4 HeXDigit)+-- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigit3 HeXDigit4)+--+-- >>> testparse parseHexDigit4 "12aF" :: Either DecodeError (HexDigit4 HeXDigit)+-- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)+--+-- >>> testparse parseHexDigit4 "aBcD" :: Either DecodeError (HexDigit4 HeXDigit)+-- Right (HexDigit4 HeXDigita HeXDigitB HeXDigitc HeXDigitD)+--+-- >>> testparsetheneof parseHexDigit4 "12aF" :: Either DecodeError (HexDigit4 HeXDigit)+-- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)+--+-- >>> testparsethennoteof parseHexDigit4 "12aFx" :: Either DecodeError (HexDigit4 HeXDigit)+-- Right (HexDigit4 HeXDigit1 HeXDigit2 HeXDigita HeXDigitF)+parseHexDigit4 ::+ ( CharParsing f, HeXaDeCiMaL digit ) =>+ f ( HexDigit4 digit )+parseHexDigit4 = HexDigit4+ <$> D.parseHeXaDeCiMaL+ <*> D.parseHeXaDeCiMaL+ <*> D.parseHeXaDeCiMaL+ <*> D.parseHeXaDeCiMaL
+ src/Waargonaut/Types/JChar/Unescaped.hs view
@@ -0,0 +1,86 @@+-- | Types and functions for handling valid unescaped characters in JSON.+module Waargonaut.Types.JChar.Unescaped+ (+ -- * Types+ Unescaped (..)+ , AsUnescaped (..)++ -- * Parser+ , parseUnescaped+ ) where++import Prelude (Eq, Ord (..), Show, (&&), (==), (||))++import Control.Category (id)+import Control.Lens (Prism', has, prism')++import Data.Foldable (any)+import Data.Function (($))+import Data.Functor ((<$>))++import Data.Char (Char, ord)+import Data.Maybe (Maybe (..))++import Text.Parser.Char (CharParsing, satisfy)++-- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Control.Monad (return)+-- >>> import Data.Either(Either (..), isLeft)+-- >>> import Data.Digit (HeXDigit(..))+-- >>> import qualified Data.Digit as D+-- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Utils+----++-- | Type to specify that this character is unescaped and may be represented+-- using a normal Haskell 'Char'.+newtype Unescaped =+ Unescaped Char+ deriving (Eq, Ord, Show)++-- | Typeclass for things that may used as an unescaped JChar.+class AsUnescaped a where+ _Unescaped :: Prism' a Unescaped++instance AsUnescaped Unescaped where+ _Unescaped = id++instance AsUnescaped Char where+ _Unescaped = prism'+ (\(Unescaped c) -> c)+ (\c -> if any ($ c) excluded then Nothing+ else Just (Unescaped c)+ )+ where+ excluded =+ [ (== '\NUL')+ , (== '"')+ , (== '\\')+ , \x ->+ let+ c = ord x+ in+ (c < 0x20 && c > 0x21) || -- "%x20-21"+ (c < 0x23 && c > 0x5B) || -- "%x23-5B"+ (c < 0x5D && c > 0x10FFFF) -- "%x5D-10FFFF"+ ]++-- | Parse an unescaped JSON character.+--+-- >>> testparse parseUnescaped "a"+-- Right (Unescaped 'a')+--+-- >>> testparse parseUnescaped "\8728"+-- Right (Unescaped '\8728')+--+-- >>> testparsetheneof parseUnescaped "a"+-- Right (Unescaped 'a')+--+-- >>> testparsethennoteof parseUnescaped "ax"+-- Right (Unescaped 'a')+parseUnescaped ::+ CharParsing f =>+ f Unescaped+parseUnescaped =+ Unescaped <$> satisfy (has _Unescaped)
src/Waargonaut/Types/JNumber.hs view
@@ -23,56 +23,50 @@ , _JNumberInt , _JNumberScientific - -- * Parser / Builder- , jNumberBuilder+ -- * Parser , parseJNumber -- * Other , jNumberToScientific+ , jIntToDigits ) where -import Prelude (Bool (..), Eq, Int, Integral, Ord,- Show, abs, fromIntegral, maxBound,- minBound, negate, (-), (<), (>),- (||))--import Data.Scientific (Scientific)-import qualified Data.Scientific as Sci+import Prelude (Bool (..), Eq, Int, Integral, Ord,+ Show, abs, fromIntegral, maxBound,+ minBound, negate, (-), (<), (==), (>),+ (||)) -import Control.Category (id, (.))-import Control.Lens (Lens', Prism', Rewrapped,- Wrapped (..), iso, prism, ( # ),- (^?), _Just, _Wrapped)+import Data.Scientific (Scientific)+import qualified Data.Scientific as Sci -import Control.Applicative (pure, (*>), (<$), (<$>), (<*>))-import Control.Monad (Monad, (=<<))+import Control.Category (id, (.))+import Control.Lens (Lens', Prism', Rewrapped,+ Wrapped (..), iso, prism, ( # ), (^?),+ _Just, _Wrapped) -import Control.Error.Util (note)+import Control.Applicative (pure, (*>), (<$), (<$>), (<*>))+import Control.Monad (Monad, (=<<)) -import Data.Either (Either (..))-import Data.Function (const, ($))-import Data.Functor (fmap)-import Data.Maybe (Maybe (..), fromMaybe, isJust,- maybe)-import Data.Monoid (mappend, mempty)-import Data.Semigroup ((<>))-import Data.Traversable (traverse)-import Data.Tuple (uncurry)+import Control.Error.Util (note) -import Data.List.NonEmpty (NonEmpty ((:|)), some1)-import qualified Data.List.NonEmpty as NE+import Data.Either (Either (..))+import Data.Function (const, ($))+import Data.Functor (fmap)+import Data.Maybe (Maybe (..), fromMaybe, isJust, maybe)+import Data.Semigroup ((<>))+import Data.Traversable (traverse)+import Data.Tuple (uncurry) -import Data.Foldable (asum, foldMap, length)+import Data.List.NonEmpty (NonEmpty ((:|)), some1)+import qualified Data.List.NonEmpty as NE -import Data.Digit (DecDigit)-import qualified Data.Digit as D+import Data.Foldable (asum, length) -import Text.Parser.Char (CharParsing, char)-import Text.Parser.Combinators (many, optional)+import Data.Digit (DecDigit)+import qualified Data.Digit as D -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB-import qualified Data.Text.Lazy.Builder.Int as TB+import Text.Parser.Char (CharParsing, char)+import Text.Parser.Combinators (many, optional) -- $setup -- >>> :set -XOverloadedStrings@@ -243,13 +237,18 @@ toJNum s = let (is, e) = Sci.toDecimalDigits (abs s) sign = s < 0++ mkNum hdD tlD = JNumber sign hdD (fmap Frac $ NE.nonEmpty =<< traverse (^? D.integralDecimal) tlD) (ex' e)+ mkExp isNeg expN = Just $ Exp Ee (Just isNeg) (D._NaturalDigits # fromIntegral expN)++ ex' 0 = Nothing+ ex' e' = mkExp (e' < 0) (abs (e' - 1))+ in case is of- [] -> JNumber sign JZero Nothing Nothing- [0] -> JNumber sign JZero Nothing Nothing- [d] -> JNumber sign (mkjInt d) Nothing Nothing- (d:ds) -> JNumber sign (mkjInt d)- (fmap Frac $ NE.nonEmpty =<< traverse (^? D.integralDecimal) ds)- (Just $ Exp Ee (Just $ e < 0) (D._NaturalDigits # fromIntegral (abs (e - 1))))+ [] -> JNumber sign JZero Nothing Nothing+ [0] -> JNumber sign JZero Nothing Nothing+ [d] -> JNumber sign (mkjInt d) Nothing (ex' e)+ (d:ds) -> if e == 0 then mkNum JZero is else mkNum (mkjInt d) ds -- | Parse the integer component of a JSON number. --@@ -340,12 +339,6 @@ , EE <$ char 'E' ] -eBuilder- :: E- -> Builder-eBuilder Ee = TB.singleton 'e'-eBuilder EE = TB.singleton 'E'- -- | Parse the fractional component of a JSON number. -- -- >>> testparsetheneof parseFrac "1"@@ -380,13 +373,6 @@ parseFrac = Frac <$> some1 D.parseDecimal --- | Builder for the fractional component.-fracBuilder- :: Frac- -> Builder-fracBuilder (Frac digs) =- digitsBuilder digs- -- | Parse the full exponent portion of a JSON number. -- -- >>> testparsethen parseExp "e10x"@@ -408,31 +394,6 @@ <*> optional (asum [False <$ char '+', True <$ char '-']) <*> some1 D.parseDecimal --- | Helper to provide the right symbol for the sign of the exponent.-getExpSymbol- :: Maybe Bool- -> Builder-getExpSymbol (Just True) = TB.singleton '-'-getExpSymbol (Just False) = TB.singleton '+'-getExpSymbol _ = mempty---- | Builder for a list of digits.-digitsBuilder- :: NonEmpty DecDigit- -> Builder-digitsBuilder =- foldMap (int8 . (D.integralDecimal #))- where- int8 :: Int -> Builder- int8 = TB.decimal---- | Builder for the exponent portion.-expBuilder- :: Exp- -> Builder-expBuilder (Exp e sign digs) =- eBuilder e <> getExpSymbol sign <> digitsBuilder digs- -- | Parse a JSON numeric value. -- -- >>> testparsethen parseJNumber "600x"@@ -484,28 +445,6 @@ <*> parseJInt <*> optional (char '.' *> parseFrac) <*> optional parseExp---- | Printing of JNumbers------ >>> toLazyText $ jNumberBuilder (JNumber {_minus = False, _numberint = JIntInt D.DecDigit3 [], _frac = Just (Frac (D.DecDigit4 :| [D.DecDigit5])), _expn = Just (Exp {_ex = Ee, _minusplus = Just False, _expdigits = D.DecDigit1 :| [D.DecDigit0]})})--- "3.45e+10"------ >>> toLazyText $ jNumberBuilder (JNumber {_minus = True, _numberint = JIntInt D.DecDigit3 [], _frac = Just (Frac (D.DecDigit4 :| [D.DecDigit5])), _expn = Just (Exp {_ex = Ee, _minusplus = Just True, _expdigits = D.DecDigit0 :| [D.x2]})})--- "-3.45e-02"------ >>> toLazyText $ jNumberBuilder (JNumber {_minus = False, _numberint = JIntInt D.DecDigit0 [D.DecDigit0], _frac = Nothing, _expn = Nothing})--- "00"----jNumberBuilder- :: JNumber- -> Builder-jNumberBuilder (JNumber sign digs mfrac mexp) =- s <> digits <> frac' <> expo- where- s = if sign then TB.singleton '-' else mempty- digits = digitsBuilder . jIntToDigits $ digs- frac' = foldMap (mappend (TB.singleton '.') . fracBuilder) mfrac- expo = foldMap expBuilder mexp -- | Returns a normalised 'Scientific' value or Nothing if the exponent -- is out of the range @[minBound,maxBound::Int]@
src/Waargonaut/Types/JObject.hs view
@@ -25,50 +25,49 @@ , fromMapLikeObj , _MapLikeObj - -- * Parser / Builder- , jObjectBuilder+ -- * Parser , parseJObject ) where -import Prelude (Eq, Int, Show, elem, fst, not,- otherwise, (==))+import Prelude (Eq, Int, Show, elem, fst, not,+ otherwise, (==)) -import Control.Applicative ((<*), (<*>))-import Control.Category (id, (.))-import Control.Lens (AsEmpty (..), At (..), Index,- IxValue, Ixed (..), Lens', Prism',- Rewrapped, Wrapped (..), cons,- iso, nearly, prism', to,- ( # ), (.~), (<&>), (^.), _Wrapped)-import Control.Lens.Extras (is)+import Control.Category (id, (.))+import Control.Lens (AsEmpty (..), At (..), Index,+ IxValue, Ixed (..), Lens',+ Prism', Rewrapped,+ Wrapped (..), cons, iso,+ nearly, prism', to, ( # ),+ (<&>), (^.), _Wrapped)+import Control.Lens.Extras (is) -import Control.Monad (Monad)-import Data.Bifoldable (Bifoldable (bifoldMap))-import Data.Bifunctor (Bifunctor (bimap))-import Data.Bitraversable (Bitraversable (bitraverse))-import Data.Bool (Bool (..))-import Data.Foldable (Foldable, find, foldr)-import Data.Function (($))-import Data.Functor (Functor, fmap, (<$>))-import Data.Maybe (Maybe (..), maybe)-import Data.Monoid (Monoid (mappend, mempty))-import Data.Semigroup (Semigroup ((<>)))-import Data.Text (Text)-import Data.Traversable (Traversable, traverse)+import Control.Monad (Monad)+import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Bool (Bool (..))+import Data.Foldable (Foldable, find, foldr)+import Data.Function (($))+import Data.Functor (Functor, (<$>))+import Data.Maybe (Maybe (..), maybe)+import Data.Monoid (Monoid (mappend, mempty))+import Data.Semigroup (Semigroup ((<>)))+import Data.Text (Text)+import Data.Traversable (Traversable, traverse) -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB+import qualified Data.Witherable as W -import qualified Data.Witherable as W+import Text.Parser.Char (CharParsing, char) -import Text.Parser.Char (CharParsing, char)+import Waargonaut.Types.CommaSep (CommaSeparated (..),+ parseCommaSeparated) -import Waargonaut.Types.CommaSep (CommaSeparated (..),- commaSeparatedBuilder,- parseCommaSeparated)+import Waargonaut.Types.JObject.JAssoc (HasJAssoc (..), JAssoc (..),+ jAssocAlterF, parseJAssoc) -import Waargonaut.Types.JString+import Waargonaut.Types.JString (_JStringText) + -- $setup -- >>> :set -XOverloadedStrings -- >>> import Utils@@ -80,61 +79,6 @@ -- >>> import Data.Digit (HeXDigit) ---- --- | This type represents the key-value pair inside of a JSON object.------ It is built like this so that we can preserve any whitespace information that--- may surround it.-data JAssoc ws a = JAssoc- { _jsonAssocKey :: JString- , _jsonAssocKeyTrailingWS :: ws- , _jsonAssocValPreceedingWS :: ws- , _jsonAssocVal :: a- }- deriving (Eq, Show, Functor, Foldable, Traversable)--instance Bifunctor JAssoc where- bimap f g (JAssoc k w1 w2 v) = JAssoc k (f w1) (f w2) (g v)--instance Bifoldable JAssoc where- bifoldMap f g (JAssoc _ w1 w2 v) = f w1 `mappend` f w2 `mappend` g v--instance Bitraversable JAssoc where- bitraverse f g (JAssoc k w1 w2 v) = JAssoc k <$> f w1 <*> f w2 <*> g v---- | This class allows you to write connective lenses for other data structures--- that may contain a 'JAssoc'.-class HasJAssoc c ws a | c -> ws a where- jAssoc :: Lens' c (JAssoc ws a)- jsonAssocKey :: Lens' c JString- {-# INLINE jsonAssocKey #-}- jsonAssocKeyTrailingWS :: Lens' c ws- {-# INLINE jsonAssocKeyTrailingWS #-}- jsonAssocVal :: Lens' c a- {-# INLINE jsonAssocVal #-}- jsonAssocValPreceedingWS :: Lens' c ws- {-# INLINE jsonAssocValPreceedingWS #-}- jsonAssocKey = jAssoc . jsonAssocKey- jsonAssocKeyTrailingWS = jAssoc . jsonAssocKeyTrailingWS- jsonAssocVal = jAssoc . jsonAssocVal- jsonAssocValPreceedingWS = jAssoc . jsonAssocValPreceedingWS--instance HasJAssoc (JAssoc ws a) ws a where- jAssoc = id- jsonAssocKey f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc y1 x2 x3 x4) (f x1)- {-# INLINE jsonAssocKey #-}- jsonAssocKeyTrailingWS f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc x1 y1 x3 x4) (f x2)- {-# INLINE jsonAssocKeyTrailingWS #-}- jsonAssocVal f (JAssoc x1 x2 x3 x4) = fmap (JAssoc x1 x2 x3) (f x4)- {-# INLINE jsonAssocVal #-}- jsonAssocValPreceedingWS f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc x1 x2 y1 x4) (f x3)- {-# INLINE jsonAssocValPreceedingWS #-}---- Helper function for trying to update/create a JAssoc value in some Functor.--- This function is analogus to the 'Data.Map.alterF' function.-jAssocAlterF :: (Monoid ws, Functor f) => Text -> (Maybe a -> f (Maybe a)) -> Maybe (JAssoc ws a) -> f (Maybe (JAssoc ws a))-jAssocAlterF k f mja = fmap g <$> f (_jsonAssocVal <$> mja) where- g v = maybe (JAssoc (_JStringText # k) mempty mempty v) (jsonAssocVal .~ v) mja- -- | The representation of a JSON object. -- -- The <https://tools.ietf.org/html/rfc8259#section-4 JSON RFC8259> indicates@@ -257,33 +201,13 @@ textKeyMatch :: Text -> JAssoc ws a -> Bool textKeyMatch k = (== k) . (^. jsonAssocKey . _JStringText) --- | Parse a single "key:value" pair-parseJAssoc- :: ( Monad f- , CharParsing f- )- => f ws- -> f a- -> f (JAssoc ws a)-parseJAssoc ws a = JAssoc- <$> parseJString <*> ws <* char ':' <*> ws <*> a---- | Builder for a single "key:value" pair.-jAssocBuilder- :: (ws -> Builder)- -> ((ws -> Builder) -> a -> Builder)- -> JAssoc ws a- -> Builder-jAssocBuilder ws aBuilder (JAssoc k ktws vpws v) =- jStringBuilder k <> ws ktws <> TB.singleton ':' <> ws vpws <> aBuilder ws v- -- | -- -- >>> testparse (parseJObject parseWhitespace parseWaargonaut) "{\"foo\":null }"--- Right (JObject (CommaSeparated (WS []) (Just (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = JAssoc {_jsonAssocKey = JString' [UnescapedJChar (JCharUnescaped 'f'),UnescapedJChar (JCharUnescaped 'o'),UnescapedJChar (JCharUnescaped 'o')], _jsonAssocKeyTrailingWS = WS [], _jsonAssocValPreceedingWS = WS [], _jsonAssocVal = Json (JNull (WS [Space]))}, _elemTrailing = Nothing}}))))+-- Right (JObject (CommaSeparated (WS []) (Just (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = JAssoc {_jsonAssocKey = JString' [UnescapedJChar (Unescaped 'f'),UnescapedJChar (Unescaped 'o'),UnescapedJChar (Unescaped 'o')], _jsonAssocKeyTrailingWS = WS [], _jsonAssocValPreceedingWS = WS [], _jsonAssocVal = Json (JNull (WS [Space]))}, _elemTrailing = Nothing}})))) -- -- >>> testparse (parseJObject parseWhitespace parseWaargonaut) "{\"foo\":null, }"--- Right (JObject (CommaSeparated (WS []) (Just (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = JAssoc {_jsonAssocKey = JString' [UnescapedJChar (JCharUnescaped 'f'),UnescapedJChar (JCharUnescaped 'o'),UnescapedJChar (JCharUnescaped 'o')], _jsonAssocKeyTrailingWS = WS [], _jsonAssocValPreceedingWS = WS [], _jsonAssocVal = Json (JNull (WS []))}, _elemTrailing = Just (Comma,WS [Space])}}))))+-- Right (JObject (CommaSeparated (WS []) (Just (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = JAssoc {_jsonAssocKey = JString' [UnescapedJChar (Unescaped 'f'),UnescapedJChar (Unescaped 'o'),UnescapedJChar (Unescaped 'o')], _jsonAssocKeyTrailingWS = WS [], _jsonAssocValPreceedingWS = WS [], _jsonAssocVal = Json (JNull (WS []))}, _elemTrailing = Just (Comma,WS [Space])}})))) -- parseJObject :: ( Monad f@@ -294,12 +218,3 @@ -> f (JObject ws a) parseJObject ws a = JObject <$> parseCommaSeparated (char '{') (char '}') ws (parseJAssoc ws a)---- | Construct a 'Builder' for an entire 'JObject', duplicate keys are preserved.-jObjectBuilder- :: (ws -> Builder)- -> ((ws -> Builder) -> a -> Builder)- -> JObject ws a- -> Builder-jObjectBuilder ws aBuilder (JObject c) =- commaSeparatedBuilder '{' '}' ws (jAssocBuilder ws aBuilder) c
+ src/Waargonaut/Types/JObject/JAssoc.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeFamilies #-}+-- | Types and functions for handling our representation of a key:value pair in+-- a JSON object.+module Waargonaut.Types.JObject.JAssoc+ (+ -- * Key/value pair type+ JAssoc (..)+ , HasJAssoc (..)++ -- * Parse+ , parseJAssoc++ -- * Update+ , jAssocAlterF+ ) where++import Prelude (Eq, Show)++import Control.Applicative ((<*), (<*>))+import Control.Category (id, (.))+import Control.Lens (Lens', ( # ), (.~))++import Control.Monad (Monad)+import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Foldable (Foldable)+import Data.Functor (Functor, fmap, (<$>))+import Data.Maybe (Maybe (..), maybe)+import Data.Monoid (Monoid (mappend, mempty))+import Data.Text (Text)+import Data.Traversable (Traversable)++import Text.Parser.Char (CharParsing, char)++import Waargonaut.Types.JString (JString,+ parseJString, _JStringText)++-- | This type represents the key:value pair inside of a JSON object.+--+-- It is built like this so that we can preserve any whitespace information that+-- may surround it.+data JAssoc ws a = JAssoc+ { _jsonAssocKey :: JString+ , _jsonAssocKeyTrailingWS :: ws+ , _jsonAssocValPreceedingWS :: ws+ , _jsonAssocVal :: a+ }+ deriving (Eq, Show, Functor, Foldable, Traversable)++instance Bifunctor JAssoc where+ bimap f g (JAssoc k w1 w2 v) = JAssoc k (f w1) (f w2) (g v)++instance Bifoldable JAssoc where+ bifoldMap f g (JAssoc _ w1 w2 v) = f w1 `mappend` f w2 `mappend` g v++instance Bitraversable JAssoc where+ bitraverse f g (JAssoc k w1 w2 v) = JAssoc k <$> f w1 <*> f w2 <*> g v++-- | This class allows you to write connective lenses for other data structures+-- that may contain a 'JAssoc'.+class HasJAssoc c ws a | c -> ws a where+ jAssoc :: Lens' c (JAssoc ws a)+ jsonAssocKey :: Lens' c JString+ {-# INLINE jsonAssocKey #-}+ jsonAssocKeyTrailingWS :: Lens' c ws+ {-# INLINE jsonAssocKeyTrailingWS #-}+ jsonAssocVal :: Lens' c a+ {-# INLINE jsonAssocVal #-}+ jsonAssocValPreceedingWS :: Lens' c ws+ {-# INLINE jsonAssocValPreceedingWS #-}+ jsonAssocKey = jAssoc . jsonAssocKey+ jsonAssocKeyTrailingWS = jAssoc . jsonAssocKeyTrailingWS+ jsonAssocVal = jAssoc . jsonAssocVal+ jsonAssocValPreceedingWS = jAssoc . jsonAssocValPreceedingWS++instance HasJAssoc (JAssoc ws a) ws a where+ jAssoc = id+ jsonAssocKey f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc y1 x2 x3 x4) (f x1)+ {-# INLINE jsonAssocKey #-}+ jsonAssocKeyTrailingWS f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc x1 y1 x3 x4) (f x2)+ {-# INLINE jsonAssocKeyTrailingWS #-}+ jsonAssocVal f (JAssoc x1 x2 x3 x4) = fmap (JAssoc x1 x2 x3) (f x4)+ {-# INLINE jsonAssocVal #-}+ jsonAssocValPreceedingWS f (JAssoc x1 x2 x3 x4) = fmap (\y1 -> JAssoc x1 x2 y1 x4) (f x3)+ {-# INLINE jsonAssocValPreceedingWS #-}++-- | Helper function for trying to update/create a JAssoc value in some Functor.+-- This function is analogus to the 'Data.Map.alterF' function.+jAssocAlterF+ :: ( Monoid ws+ , Functor f+ )+ => Text+ -> (Maybe a -> f (Maybe a))+ -> Maybe (JAssoc ws a)+ -> f (Maybe (JAssoc ws a))+jAssocAlterF k f mja = fmap g <$> f (_jsonAssocVal <$> mja) where+ g v = maybe (JAssoc (_JStringText # k) mempty mempty v) (jsonAssocVal .~ v) mja++-- | Parse a single "key:value" pair+parseJAssoc+ :: ( Monad f+ , CharParsing f+ )+ => f ws+ -> f a+ -> f (JAssoc ws a)+parseJAssoc ws a = JAssoc+ <$> parseJString <*> ws <* char ':' <*> ws <*> a
src/Waargonaut/Types/JString.hs view
@@ -17,46 +17,36 @@ , _JStringText , stringToJString - -- * Parser / Builder+ -- * Parser , parseJString- , jStringBuilder ) where import Prelude (Eq, Ord, Show, String, foldr) -import Control.Applicative ((*>), (<*))-import Control.Category (id, (.))-import Control.Error.Util (note)-import Control.Lens (Prism', Rewrapped, Wrapped (..),- iso, prism, review, ( # ), (^?))--import Data.Bifunctor (first)-import Data.Either (Either (Right))-import Data.Foldable (Foldable, foldMap)-import Data.Function (const, ($))-import Data.Functor (Functor, fmap, (<$>))-import Data.Semigroup ((<>))-import Data.Text (Text)-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import Data.Traversable (Traversable, traverse)--import Data.Vector (Vector)-import qualified Data.Vector as V+import Control.Applicative (Applicative, (*>), (<*))+import Control.Category (id, (.))+import Control.Error.Util (note)+import Control.Lens (Prism', Profunctor, Rewrapped,+ Wrapped (..), iso, prism, review) -import Data.Digit (HeXDigit)+import Data.Either (Either (Right))+import Data.Foldable (Foldable)+import Data.Function (($))+import Data.Functor (Functor, fmap, (<$>))+import Data.Text (Text)+import qualified Data.Text as Text+import Data.Traversable (Traversable, traverse) -import Text.Parser.Char (CharParsing, char)-import Text.Parser.Combinators (many)+import Data.Vector (Vector)+import qualified Data.Vector as V -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB+import Data.Digit (HeXDigit) -import qualified Data.ByteString.Lazy.Char8 as BS8+import Text.Parser.Char (CharParsing, char)+import Text.Parser.Combinators (many) -import Waargonaut.Types.JChar (JChar, jCharBuilderTextL,- parseJChar, utf8CharToJChar,- _JChar)+import Waargonaut.Types.JChar (JChar, charToJChar, jCharToChar,+ parseJChar, utf8CharToJChar) -- $setup -- >>> :set -XOverloadedStrings@@ -69,6 +59,9 @@ -- >>> import Utils -- >>> import Waargonaut.Decode.Error (DecodeError) -- >>> import Waargonaut.Types.Whitespace+-- >>> import Waargonaut.Types.JChar.Unescaped+-- >>> import Waargonaut.Types.JChar.Escaped+-- >>> import Waargonaut.Types.JChar.HexDigit4 -- >>> import Waargonaut.Types.JChar -- >>> import Data.Text.Lazy.Builder (toLazyText) ----@@ -102,18 +95,16 @@ instance AsJString String where _JString = prism- (\(JString' cx) -> V.toList $ (_JChar #) <$> cx)- (\x -> JString' . V.fromList <$> traverse (note x . (^? _JChar)) x)+ (\(JString' cx) -> V.toList $ jCharToChar <$> cx)+ (\x -> JString' . V.fromList <$> traverse (note x . charToJChar) x) --- | Prism between a 'JString' and 'Text'.+-- | Conversion between a 'JString' and 'Text'. -- -- JSON strings a wider range of encodings than 'Text' and to be consistent with -- the 'Text' type, these invalid types are replaced with a placeholder value. ---_JStringText :: Prism' JString Text-_JStringText = prism- (JString' . V.fromList . fmap utf8CharToJChar . Text.unpack)- (\x -> first (const x) . Text.decodeUtf8' . BS8.toStrict . BS8.pack . review _JString $ x)+_JStringText :: (Profunctor p, Applicative f) => p Text (f Text) -> p JString (f JString)+_JStringText = iso (Text.pack . review _JString) (JString' . V.fromList . fmap utf8CharToJChar . Text.unpack) -- | Parse a 'JString', storing escaped characters and any explicitly escaped -- character encodings '\uXXXX'.@@ -125,50 +116,24 @@ -- Right (JString' [EscapedJChar ReverseSolidus]) -- -- >>> testparse parseJString "\"abc\""--- Right (JString' [UnescapedJChar (JCharUnescaped 'a'),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')])+-- Right (JString' [UnescapedJChar (Unescaped 'a'),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) -- -- >>> testparse parseJString "\"a\\rbc\""--- Right (JString' [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')])+-- Right (JString' [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) -- -- >>> testparse parseJString "\"a\\rbc\\uab12\\ndef\\\"\"" :: Either DecodeError JString--- Right (JString' [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (JCharUnescaped 'd'),UnescapedJChar (JCharUnescaped 'e'),UnescapedJChar (JCharUnescaped 'f'),EscapedJChar QuotationMark])+-- Right (JString' [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (Unescaped 'd'),UnescapedJChar (Unescaped 'e'),UnescapedJChar (Unescaped 'f'),EscapedJChar QuotationMark]) -- -- >>> testparsethennoteof parseJString "\"a\"\\u"--- Right (JString' [UnescapedJChar (JCharUnescaped 'a')])+-- Right (JString' [UnescapedJChar (Unescaped 'a')]) -- -- >>> testparsethennoteof parseJString "\"a\"\t"--- Right (JString' [UnescapedJChar (JCharUnescaped 'a')])+-- Right (JString' [UnescapedJChar (Unescaped 'a')]) parseJString :: CharParsing f => f JString parseJString = char '"' *> (JString' . V.fromList <$> many parseJChar) <* char '"'---- | Builder for a 'JString'.------ >>> toLazyText $ jStringBuilder ((JString' V.empty) :: JString)--- "\"\""------ >>> toLazyText $ jStringBuilder ((JString' $ V.fromList [UnescapedJChar (JCharUnescaped 'a'),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')]) :: JString)--- "\"abc\""------ >>> toLazyText $ jStringBuilder ((JString' $ V.fromList [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')]) :: JString)--- "\"a\\rbc\""------ >>> toLazyText $ jStringBuilder ((JString' $ V.fromList [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (JCharUnescaped 'd'),UnescapedJChar (JCharUnescaped 'e'),UnescapedJChar (JCharUnescaped 'f'),EscapedJChar QuotationMark]) :: JString)--- "\"a\\rbc\\uab12\\ndef\\\"\""------ >>> toLazyText $ jStringBuilder ((JString' $ V.singleton (UnescapedJChar (JCharUnescaped 'a'))) :: JString)--- "\"a\""------ >>> toLazyText $ jStringBuilder (JString' $ V.singleton (EscapedJChar ReverseSolidus) :: JString)--- "\"\\\\\""----jStringBuilder- :: JString- -> Builder-jStringBuilder (JString' jcs) =- TB.singleton '\"' <> foldMap jCharBuilderTextL jcs <> TB.singleton '\"' -- | Convert a 'String' to a 'JString'. stringToJString :: String -> JString
src/Waargonaut/Types/Json.hs view
@@ -20,8 +20,7 @@ -- * Top level JSON type , Json (..) - -- * Parser / Builder- , waargonautBuilder+ -- * Parser , parseWaargonaut -- * Traversals@@ -36,7 +35,6 @@ , aix ) where - import Prelude (Eq, Int, Show) import Control.Applicative (pure, (<$>), (<*>), (<|>))@@ -58,26 +56,20 @@ import Data.Function (flip) import Data.Functor (Functor (..)) import Data.Monoid (Monoid (..))-import Data.Semigroup (Semigroup, (<>))+import Data.Semigroup (Semigroup) import Data.Traversable (Traversable (..)) import Data.Tuple (uncurry) import Data.Maybe (Maybe) import Data.Text (Text) -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB- import Text.Parser.Char (CharParsing, text) -import Waargonaut.Types.JArray (JArray (..), jArrayBuilder,- parseJArray)-import Waargonaut.Types.JNumber (JNumber, jNumberBuilder,- parseJNumber)-import Waargonaut.Types.JObject (JObject (..), jObjectBuilder,- parseJObject, _MapLikeObj)-import Waargonaut.Types.JString (JString, jStringBuilder,- parseJString)+import Waargonaut.Types.JArray (JArray (..), parseJArray)+import Waargonaut.Types.JNumber (JNumber, parseJNumber)+import Waargonaut.Types.JObject (JObject (..), parseJObject,+ _MapLikeObj)+import Waargonaut.Types.JString (JString, parseJString) import Waargonaut.Types.Whitespace (WS (..), parseWhitespace) -- $setup@@ -88,12 +80,13 @@ -- >>> import Data.Either (Either (..), isLeft) -- >>> import Data.Function (($)) -- >>> import Waargonaut.Decode.Error (DecodeError)+-- >>> import Waargonaut.Types.JChar.Unescaped (Unescaped (..)) -- >>> import Data.Digit (HeXDigit) -- >>> import qualified Waargonaut.Encode as E--- >>> let intList = E.runPureEncoder (E.list E.int) [1,2,3]+-- >>> let intList = E.asJson' (E.list E.int) [1,2,3] -- >>> data Foo = Foo { fooA :: Int, fooB :: Text } deriving Show -- >>> let encodeFoo = E.mapLikeObj $ \(Foo i t) -> E.atKey' "a" E.int i . E.atKey' "b" E.text t--- >>> let obj = E.runPureEncoder encodeFoo (Foo 33 "Fred")+-- >>> let obj = E.asJson' encodeFoo (Foo 33 "Fred") ---- -- | Individual JSON Types and their trailing whitespace.@@ -216,24 +209,12 @@ jtypeTraversal :: Traversal (JType ws a) (JType ws a') a a' jtypeTraversal = bitraverse pure --- | Using the provided whitespace builder, create a builder for a given 'JType'.-jTypesBuilder- :: (WS -> Builder)- -> JType WS Json- -> Builder-jTypesBuilder s (JNull tws) = TB.fromText "null" <> s tws-jTypesBuilder s (JBool b tws) = TB.fromText (if b then "true" else "false") <> s tws-jTypesBuilder s (JNum jn tws) = jNumberBuilder jn <> s tws-jTypesBuilder s (JStr js tws) = jStringBuilder js <> s tws-jTypesBuilder s (JArr js tws) = jArrayBuilder s waargonautBuilder js <> s tws-jTypesBuilder s (JObj jobj tws) = jObjectBuilder s waargonautBuilder jobj <> s tws- -- | -- A 'Control.Lens.Traversal'' over the 'a' at the given 'Text' key on a JSON object. ----- >>> E.simplePureEncodeNoSpaces E.json (obj & oat "c" ?~ E.runPureEncoder E.int 33)+-- >>> E.simplePureEncodeTextNoSpaces E.json (obj & oat "c" ?~ E.asJson' E.int 33) -- "{\"c\":33,\"a\":33,\"b\":\"Fred\"}"--- >>> E.simplePureEncodeNoSpaces E.json (obj & oat "d" ?~ E.runPureEncoder E.text "sally")+-- >>> E.simplePureEncodeTextNoSpaces E.json (obj & oat "d" ?~ E.asJson' E.text "sally") -- "{\"d\":\"sally\",\"a\":33,\"b\":\"Fred\"}" -- oat :: (AsJType r ws a, Semigroup ws, Monoid ws) => Text -> Traversal' r (Maybe a)@@ -242,9 +223,9 @@ -- | -- A 'Control.Lens.Traversal'' over the 'a' at the given 'Int' position in a JSON object. ----- >>> E.simplePureEncodeNoSpaces E.json (obj & oix 0 .~ E.runPureEncoder E.int 1)+-- >>> E.simplePureEncodeTextNoSpaces E.json (obj & oix 0 .~ E.asJson' E.int 1) -- "{\"a\":1,\"b\":\"Fred\"}"--- >>> E.simplePureEncodeNoSpaces E.json (obj & oix 1 .~ E.runPureEncoder E.text "sally")+-- >>> E.simplePureEncodeTextNoSpaces E.json (obj & oix 1 .~ E.asJson' E.text "sally") -- "{\"a\":33,\"b\":\"sally\"}" oix :: (Semigroup ws, Monoid ws, AsJType r ws a) => Int -> Traversal' r a oix i = _JObj . _1 . ix i@@ -252,9 +233,9 @@ -- | -- A 'Control.Lens.Traversal'' over the 'a' at the given 'Int' position in a JSON array. ----- >>> E.simplePureEncodeNoSpaces E.json ((E.runPureEncoder (E.list E.int) [1,2,3]) & aix 0 .~ E.runPureEncoder E.int 99)+-- >>> E.simplePureEncodeTextNoSpaces E.json ((E.asJson' (E.list E.int) [1,2,3]) & aix 0 .~ E.asJson' E.int 99) -- "[99,2,3]"--- >>> E.simplePureEncodeNoSpaces E.json ((E.runPureEncoder (E.list E.int) [1,2,3]) & aix 2 .~ E.runPureEncoder E.int 44)+-- >>> E.simplePureEncodeTextNoSpaces E.json ((E.asJson' (E.list E.int) [1,2,3]) & aix 2 .~ E.asJson' E.int 44) -- "[1,2,44]" aix :: (AsJType r ws a, Semigroup ws, Monoid ws) => Int -> Traversal' r a aix i = _JArr . _1 . ix i@@ -327,25 +308,25 @@ -- Right (JStr (JString' []) ()) -- -- >>> testparse (parseJStr (return ())) "\"abc\""--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a'),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a'),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) ()) -- -- >>> testparse (parseJStr (return ())) "\"a\\rbc\""--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) ()) -- -- >>> testparse (parseJStr (return ())) "\"a\\rbc\\uab12\\ndef\\\"\"" :: Either DecodeError (JType () a)--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (JCharUnescaped 'd'),UnescapedJChar (JCharUnescaped 'e'),UnescapedJChar (JCharUnescaped 'f'),EscapedJChar QuotationMark]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a'),EscapedJChar (WhiteSpace CarriageReturn),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c'),EscapedJChar (Hex (HexDigit4 HeXDigita HeXDigitb HeXDigit1 HeXDigit2)),EscapedJChar (WhiteSpace NewLine),UnescapedJChar (Unescaped 'd'),UnescapedJChar (Unescaped 'e'),UnescapedJChar (Unescaped 'f'),EscapedJChar QuotationMark]) ()) -- -- >>> testparsetheneof (parseJStr (return ())) "\"\"" -- Right (JStr (JString' []) ()) -- -- >>> testparsetheneof (parseJStr (return ())) "\"abc\""--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a'),UnescapedJChar (JCharUnescaped 'b'),UnescapedJChar (JCharUnescaped 'c')]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a'),UnescapedJChar (Unescaped 'b'),UnescapedJChar (Unescaped 'c')]) ()) -- -- >>> testparsethennoteof (parseJStr (return ())) "\"a\"\\u"--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a')]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a')]) ()) -- -- >>> testparsethennoteof (parseJStr (return ())) "\"a\"\t"--- Right (JStr (JString' [UnescapedJChar (JCharUnescaped 'a')]) ())+-- Right (JStr (JString' [UnescapedJChar (Unescaped 'a')]) ()) parseJStr :: CharParsing f => f ws@@ -389,14 +370,6 @@ , parseJArr , parseJObj ]---- | Using the given whitespace builder, create a builder for a given 'Json' value.-waargonautBuilder- :: (WS -> Builder)- -> Json- -> Builder-waargonautBuilder ws (Json jt) =- jTypesBuilder ws jt -- | Parse to a 'Json' value, keeping all of the information about the leading -- and trailing whitespace.
src/Waargonaut/Types/Whitespace.hs view
@@ -15,8 +15,6 @@ , parseWhitespace , parseSomeWhitespace - , wsBuilder- , wsRemover ) where import Control.Applicative (liftA2)@@ -26,9 +24,6 @@ to, uncons, (^.), _2, _Wrapped) import Control.Lens.Extras (is) -import Data.Text.Lazy.Builder (Builder)-import qualified Data.Text.Lazy.Builder as TB- import Data.Vector (Vector) import qualified Data.Vector as V @@ -169,22 +164,3 @@ escapedWhitespaceChar CarriageReturn = '\r' escapedWhitespaceChar NewLine = '\n' {-# INLINE escapedWhitespaceChar #-}---- | Create a 'Data.ByteString.Builder' from a 'Whitespace'-whitespaceBuilder :: Whitespace -> Builder-whitespaceBuilder Space = TB.singleton ' '-whitespaceBuilder HorizontalTab = TB.singleton '\t'-whitespaceBuilder LineFeed = TB.singleton '\f'-whitespaceBuilder CarriageReturn = TB.singleton '\r'-whitespaceBuilder NewLine = TB.singleton '\n'-{-# INLINE whitespaceBuilder #-}---- | Reconstitute the given whitespace into its original form.-wsBuilder :: WS -> Builder-wsBuilder (WS ws) = foldMap whitespaceBuilder ws-{-# INLINE wsBuilder #-}---- | Remove any whitespace. Minification for free, yay!-wsRemover :: WS -> Builder-wsRemover = const mempty-{-# INLINE wsRemover #-}
test/Decoder.hs view
@@ -8,26 +8,35 @@ import Prelude (Char, Eq, Int, Show (show), String, print, (==)) -import Control.Applicative (liftA3, (<$>))+import Control.Applicative (liftA3, pure, (<$>)) import Control.Category ((.))+import Control.Lens (preview) import Control.Monad (Monad, (>=>), (>>=)) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (Assertion, assertBool, assertEqual, assertFailure, testCase, (@?=)) +import Hedgehog (Property, evalIO, property,+ withTests, (/==), (===))+import Test.Tasty.Hedgehog (testProperty)+ import Data.Bool (Bool (..)) import qualified Data.ByteString as BS import qualified Data.Either as Either import Data.Function (const, ($))+import Data.Functor (fmap) import Data.Maybe (Maybe (Just, Nothing)) import Data.Semigroup (Semigroup ((<>))) import qualified Data.Sequence as Seq import Data.Tagged (untag) import Data.Text (Text)+import qualified Data.Text as T import qualified Natural as N +import Waargonaut.Lens (_String)+ import Waargonaut.Generic (mkDecoder) import Waargonaut.Decode.Internal (ZipperMove (BranchFail),@@ -36,14 +45,16 @@ import qualified Waargonaut.Decode as D import qualified Waargonaut.Decode.Error as D -import Types.Common (imageDecodeSuccinct, parseBS,+import qualified Waargonaut.Attoparsec as WA++import Types.Common (imageDecodeSuccinct, testImageDataType) decoderTests :: TestTree decoderTests = testGroup "Decoding"- [ testCase "Image (test1.json)" decodeTest1Json- , testCase "[Int]" decodeTest2Json- , testCase "(Char,String,[Int])" decodeTest3Json+ [ testCase "Image Record" decodeImageObjJson+ , testCase "[Int]" decodeIntListJson+ , testCase "(Char,String,[Int])" decodeTripleJson , testCase "Fail with Bad Key" decodeTestBadObjKey , testCase "Fail with Missing Key" decodeTestMissingObjKey , testCase "Enum" decodeTestEnum@@ -55,12 +66,66 @@ , testCase "Object Decoder" objectAsKeyValuesDecoder , testCase "Absent Key Decoder" absentKeyDecoder , testCase "Either decoding order - Right first" decodeEitherRightFirst+ , testProperty "Unicode codepoint handling regression" unicodeHandlingRegression ] +unicodeHandlingRegression :: Property+unicodeHandlingRegression = withTests 1 . property $ do+ let+ -- Prepare a decoder function+ dec = WA.pureDecodeAttoparsecByteString++ -- Decoder for JSON -> Text+ decText = dec D.text+ -- Decoder for JSON -> Json+ decJson = dec D.json++ -- Manual created JSON "String" input+ manualInput = "\"\\u2705\""++ -- what the above JSON string should parse into.+ strGood = ("\x2705" :: String)++ -- what issue #58 claims is produced by parsing to 'Text'+ strBad = ("\x05" :: String)++ -- This is the expected 'Text' value+ expectedText = Either.Right ("\x2705" :: Text)++ -- Read the JSON string in from a file to try to avoid differences from+ -- creating the text input via haskell values.+ fileInput <- evalIO $ BS.readFile "test/json-data/unicode_2705.json"++ let+ -- Decode the manual and file inputs to 'Text'+ fileInputDecoded = decText fileInput+ manualInputDecoded = decText manualInput++ -- Decode the manual and file inputs to their 'Json' representations+ fileInputJson = decJson fileInput+ manualInputJson = decJson manualInput++ -- Do the 'Text' decoded values match our expectations+ fileInputDecoded === expectedText+ manualInputDecoded === expectedText++ -- If we decode to 'Json' and then use the prism, do we still get the required+ -- string. There should be no reason this is different to decoding to text.+ -- Key words being "should be".+ (fmap (preview _String) fileInputJson) === fmap pure expectedText+ (fmap (preview _String) manualInputJson) === fmap pure expectedText++ -- For comparison, take the expected good/bad 'String' values and pack them to 'Text'.+ Either.Right (T.pack strGood) === fileInputDecoded+ Either.Right (T.pack strGood) === manualInputDecoded++ Either.Right (T.pack strBad) /== fileInputDecoded+ Either.Right (T.pack strBad) /== manualInputDecoded+ nonEmptyDecoder :: Assertion nonEmptyDecoder = do let- dec = D.runPureDecode (D.nonempty D.int) parseBS . D.mkCursor+ dec = WA.pureDecodeAttoparsecByteString (D.nonempty D.int) ok = "[1]" notOkay = "[]"@@ -81,7 +146,7 @@ listDecoder :: Assertion listDecoder = do let- dec = D.runPureDecode (D.list D.int) parseBS . D.mkCursor+ dec = WA.pureDecodeAttoparsecByteString (D.list D.int) ok = "[1,2,3]" okE = "[]"@@ -101,7 +166,7 @@ objectAsKeyValuesDecoder :: Assertion objectAsKeyValuesDecoder = do let- dec = D.runPureDecode (D.objectAsKeyValues D.text D.int) parseBS . D.mkCursor+ dec = WA.pureDecodeAttoparsecByteString (D.objectAsKeyValues D.text D.int) ok = "{\"1\":1,\"2\":2,\"3\":3}" okE = "{}"@@ -127,7 +192,7 @@ d = D.withCursor $ D.down >=> D.fromKey "bar" D.int - r <- D.runDecode d parseBS (D.mkCursor j)+ let r = WA.pureDecodeAttoparsecByteString d j Either.either (\(e, _) -> assertBool "Incorrect Error - Expected KeyDecodeFailed" (e == D.KeyNotFound "bar"))@@ -141,33 +206,33 @@ d = D.withCursor $ D.down >=> D.fromKey "foo" D.int - r <- D.runDecode d parseBS (D.mkCursor j)+ let r = WA.pureDecodeAttoparsecByteString d j Either.either (\(e, _) -> assertBool "Incorrect Error - Expected KeyDecodeFailed" (e == D.KeyDecodeFailed) ) (\_ -> assertFailure "Expected Error!") r -decodeTest1Json :: Assertion-decodeTest1Json = D.runPureDecode imageDecodeSuccinct parseBS . D.mkCursor- <$> BS.readFile "test/json-data/test1.json"+decodeImageObjJson :: Assertion+decodeImageObjJson = WA.pureDecodeAttoparsecByteString imageDecodeSuccinct+ <$> BS.readFile "test/json-data/image_obj.json" >>= Either.either failWithHistory (assertEqual "Image Decode Failed" testImageDataType) where failWithHistory (err, hist) = do print err print (ppCursorHistory hist)- assertFailure "Decode Failed :("+ assertFailure "Decode Failed" -decodeTest2Json :: Assertion-decodeTest2Json = assertBool "[Int] Decode Success" . Either.isRight- $ D.runPureDecode listDecode parseBS (D.mkCursor "[23,44]")+decodeIntListJson :: Assertion+decodeIntListJson = assertBool "[Int] Decode Success" . Either.isRight+ $ WA.pureDecodeAttoparsecByteString listDecode "[23,44]" where listDecode :: Monad f => D.Decoder f [Int] listDecode = untag mkDecoder -decodeTest3Json :: Assertion-decodeTest3Json = assertBool "(Char,String,[Int]) Decode Success" . Either.isRight- $ D.runPureDecode decoder parseBS (D.mkCursor "[\"a\",\"fred\",1,2,3,4]")+decodeTripleJson :: Assertion+decodeTripleJson = assertBool "(Char,String,[Int]) Decode Success" . Either.isRight+ $ WA.pureDecodeAttoparsecByteString decoder "[\"a\",\"fred\",1,2,3,4]" where decoder :: Monad f => D.Decoder f (Char,String,[Int]) decoder = D.withCursor $ D.down >=> \fstElem -> liftA3 (,,)@@ -195,47 +260,57 @@ chk "\"c\"" C where chk i o =- D.runPureDecode decodeMyEnum parseBS (D.mkCursor i) @?= (Either.Right o)+ WA.pureDecodeAttoparsecByteString decodeMyEnum i @?= (Either.Right o) decodeTestEnumError :: Assertion-decodeTestEnumError = D.runDecode decodeMyEnum parseBS (D.mkCursor "\"WUT\"")- >>= Either.either+decodeTestEnumError =+ let+ i = WA.pureDecodeAttoparsecByteString decodeMyEnum "\"WUT\""+ in+ Either.either (\(e, _) -> assertBool "Incorrect Error!" (e == D.ConversionFailure "MyEnum")) (const (assertFailure "Should not succeed"))+ i decodeEitherAlt :: Monad f => D.Decoder f (Either.Either Text Int) decodeEitherAlt = D.either D.text D.int decodeEitherRightFirst :: Assertion decodeEitherRightFirst = do- let d = D.runPureDecode (D.either D.scientific D.int) parseBS . D.mkCursor+ let d = WA.pureDecodeAttoparsecByteString (D.either D.scientific D.int) d "44e333" @?= Either.Right (Either.Left 44e333) d "33" @?= Either.Right (Either.Right 33) decodeAlt :: Assertion decodeAlt = do- t <- D.runDecode decodeEitherAlt parseBS (D.mkCursor "\"FRED\"")- i <- D.runDecode decodeEitherAlt parseBS (D.mkCursor "33")+ let+ t = WA.pureDecodeAttoparsecByteString decodeEitherAlt "\"FRED\""+ i = WA.pureDecodeAttoparsecByteString decodeEitherAlt "33" t @?= Either.Right (Either.Left "FRED") i @?= Either.Right (Either.Right 33) decodeAltError :: Assertion-decodeAltError = D.runDecode decodeEitherAlt parseBS (D.mkCursor "{\"foo\":33}")- >>= Either.either+decodeAltError =+ let+ i = WA.pureDecodeAttoparsecByteString decodeEitherAlt "{\"foo\":33}"+ in+ Either.either (\(_,h) -> assertBool "BranchFail error not found in history" $ case Seq.viewr (unCursorHistory' h) of _ Seq.:> (BranchFail _, _) -> True _ -> False ) (\_ -> assertFailure "Alt Error Test should fail")+ i absentKeyDecoder :: Assertion absentKeyDecoder = do- a <- D.runDecode (D.atKeyOptional "key" D.text) parseBS (D.mkCursor "{\"key\":\"present\"}")- b <- D.runDecode (D.atKeyOptional "missing" D.text) parseBS (D.mkCursor "{\"key\":\"present\"}")- c <- D.runDecode (D.atKeyOptional "key" D.int) parseBS (D.mkCursor "{\"key\":\"present\"}")+ let+ a = WA.pureDecodeAttoparsecByteString (D.atKeyOptional "key" D.text) "{\"key\":\"present\"}"+ b = WA.pureDecodeAttoparsecByteString (D.atKeyOptional "missing" D.text) "{\"key\":\"present\"}"+ c = WA.pureDecodeAttoparsecByteString (D.atKeyOptional "key" D.int) "{\"key\":\"present\"}" a @?= Either.Right (Just "present") b @?= Either.Right Nothing
test/Decoder/Laws.hs view
@@ -16,16 +16,15 @@ import Hedgehog import qualified Hedgehog.Gen as Gen +import qualified Waargonaut.Attoparsec as WA import qualified Waargonaut.Decode as D import Waargonaut.Decode.Error (DecodeError (ConversionFailure)) import Waargonaut.Decode.Types (Decoder) -import Types.Common (parseBS)- import qualified Laws runD :: Decoder Identity a -> Either (DecodeError, D.CursorHistory) a-runD d = D.runPureDecode d parseBS (D.mkCursor "true")+runD d = WA.pureDecodeAttoparsecText d "true" newtype ShowDecoder a = SD (Decoder Identity a) deriving (Functor, Monad, Applicative)
test/Encoder.hs view
@@ -59,7 +59,7 @@ -> Text -> TestTree tCase nm enc a expected = testCase nm $- E.simplePureEncodeNoSpaces enc a @?= expected+ E.simplePureEncodeTextNoSpaces enc a @?= expected encoderTests :: TestTree encoderTests = testGroup "Encoder"
test/Encoder/Laws.hs view
@@ -19,7 +19,7 @@ import qualified Laws runSE :: ShowEncoder a -> a -> Text-runSE (SE e) = E.simplePureEncodeNoSpaces e+runSE (SE e) = E.simplePureEncodeTextNoSpaces e newtype ShowEncoder a = SE (Encoder Identity a)
+ test/Golden.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE NoImplicitPrelude #-}+module Golden (goldenTests) where++import Control.Applicative (pure, (*>))+import Control.Category ((.))+import Control.Monad ((>=>))++import System.Exit (exitFailure)+import System.FilePath (FilePath, takeBaseName)+import System.IO (IO, print)++import Data.Either (either)+import Data.Function (($))++import Data.ByteString.Lazy (ByteString, readFile, toStrict)++import Data.Attoparsec.ByteString (parseOnly)++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Golden (findByExtension, goldenVsString)++import qualified Waargonaut.Decode as D+import qualified Waargonaut.Encode as E++readAndEncodeFile :: FilePath -> IO ByteString+readAndEncodeFile = readFile+ >=> D.decodeFromByteString parseOnly D.json . toStrict+ >=> either (\err -> print err *> exitFailure) pure+ >=> E.simpleEncodeByteString E.json++goldenTests :: IO TestTree+goldenTests = do+ fs <- findByExtension [".golden"] "test/json-data/goldens"+ pure . testGroup "Golden Tests" $+ [ goldenVsString (takeBaseName input) input (readAndEncodeFile input)+ | input <- fs+ ]
test/Json.hs view
@@ -1,24 +1,102 @@+{-# LANGUAGE RankNTypes #-} module Json- ( jsonTests+ ( jsonPrisms ) where -import Control.Lens (review,preview,_Empty)+import Control.Applicative (liftA2)+import Control.Lens (Prism', preview, review, _Empty)+ import Test.Tasty-import Test.Tasty.HUnit+import Test.Tasty.Hedgehog (testProperty)+import Test.Tasty.HUnit (testCase, (@?=))++import Hedgehog (Gen, Property, forAll, property, (===))+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Data.Vector (Vector)+import qualified Data.Vector as V++import Data.HashMap.Strict (HashMap)+import qualified Data.HashMap.Strict as HM++import Data.Text (Text)++import qualified Data.Attoparsec.Text as AT+ import Waargonaut.Types +import Waargonaut.Lens (_ArrayOf, _Bool, _Number, _ObjHashMapOf,+ _String, _TextJson) -jsonTests :: TestTree-jsonTests =- testGroup "Json types"- [ testCase "CommandSepareted's _Empty prism law"+import Types.Common (genScientific, genText)+import Types.Json (genJson)++prismLaw :: (Eq a, Show a) => Gen a -> Prism' b a -> Property+prismLaw genA prismA = property $ forAll genA >>= \a ->+ preview prismA (review prismA a) === Just a++emptyPrismLaw :: TestTree+emptyPrismLaw =+ testGroup "_Empty"+ [ testCase "CommaSeparated" $ preview _Empty (review _Empty () :: CommaSeparated WS (JAssoc WS Json)) @?= Just ()- , testCase "JObject's _Empty prism law"+ , testCase "JObject" $ preview _Empty (review _Empty () :: JObject WS Json) @?= Just ()- , testCase "JArray's _Empty prism law"+ , testCase "JArray" $ preview _Empty (review _Empty () :: JArray WS Json) @?= Just ()- , testCase "MapLikeObj's _Empty prism law"+ , testCase "MapLikeObj" $ preview _Empty (review _Empty () :: MapLikeObj WS Json) @?= Just ()- , testCase "WS's _Empty prism law"+ , testCase "WS" $ preview _Empty (review _Empty () :: WS) @?= Just () ]++objHashMapPrismLaws :: TestTree+objHashMapPrismLaws = testGroup "Json hashmap prism"+ [ testProperty "_ObjHashMapOf Scientific"+ $ prismLaw (genHashMapOf $ genScientific (Just 10)) (_ObjHashMapOf _Number)++ , testProperty "_ObjHashMapOf Text"+ $ prismLaw (genHashMapOf genText) (_ObjHashMapOf _String)++ , testProperty "_ObjHashMapOf Bool"+ $ prismLaw (genHashMapOf Gen.bool) (_ObjHashMapOf _Bool)++ , testProperty "_ObjHashMapOf Json"+ $ prismLaw (genHashMapOf genJson) (_ObjHashMapOf (_String . _TextJson AT.parseOnly))+ ]++arrayOfPrismLaws :: TestTree+arrayOfPrismLaws = testGroup "Json array prism"+ [ testProperty "_ArrayOf Scientific"+ $ prismLaw (genListOf $ genScientific (Just 10)) (_ArrayOf _Number)++ , testProperty "_ArrayOf Text"+ $ prismLaw (genListOf genText) (_ArrayOf _String)++ , testProperty "_ArrayOf Bool"+ $ prismLaw (genListOf Gen.bool) (_ArrayOf _Bool)++ , testProperty "_ArrayOf Json"+ $ prismLaw (genListOf genJson) (_ArrayOf (_String . _TextJson AT.parseOnly))+ ]++jsonPrisms :: TestTree+jsonPrisms =+ testGroup "Json 'Prisms'' must OBEY THE LAW: (preview p (review p x) == Just x)"+ [ testProperty "_Bool" $ prismLaw Gen.bool _Bool+ , testProperty "_Number" $ prismLaw (genScientific (Just 10)) _Number+ , testProperty "_TextJson" $ prismLaw genJson (_TextJson AT.parseOnly)+ , testProperty "_String" $ prismLaw genText _String++ , arrayOfPrismLaws+ , objHashMapPrismLaws+ , emptyPrismLaw+ ]++genHashMapOf :: Gen a -> Gen (HashMap Text a)+genHashMapOf genElem = HM.fromList <$> Gen.list (Range.linear 0 100) tup+ where tup = liftA2 (,) genText genElem++genListOf :: Gen a -> Gen (Vector a)+genListOf genElem = V.fromList <$> Gen.list (Range.linear 0 100) genElem
test/Main.hs view
@@ -2,350 +2,93 @@ {-# LANGUAGE TupleSections #-} module Main (main) where -import GHC.Word (Word8)--import Control.Lens (( # ), (^.), (^?), _2)-import qualified Control.Lens as L-import Control.Monad (when)--import Data.Either (isLeft)--import qualified Data.Scientific as Sci+import GHC.Word (Word8) -import Data.Functor.Contravariant ((>$<))-import Data.Maybe (fromMaybe)-import Data.Semigroup ((<>))-import Data.Text (Text)-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Text.IO as Text+import Data.Either (isLeft) -import qualified Data.Text.Lazy as TextL-import qualified Data.Text.Lazy.Builder as TB+import Data.Semigroup ((<>)) -import qualified Data.ByteString as BS+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Text.IO as Text -import qualified Data.Sequence as S+import qualified Data.Text.Lazy as TextL -import Hedgehog-import qualified Hedgehog.Gen as Gen-import qualified Hedgehog.Range as Range+import qualified Data.ByteString as BS import Test.Tasty-import Test.Tasty.Hedgehog import Test.Tasty.HUnit -import Natural (_Natural)--import Data.Digit (HeXDigit)--import Waargonaut (Json)-import qualified Waargonaut as W-import qualified Waargonaut.Types.CommaSep as CommaSep--import Waargonaut.Types.JChar (JChar)-import qualified Waargonaut.Types.JChar as JChar--import qualified Waargonaut.Types.JNumber as JNumber-import qualified Waargonaut.Types.Whitespace as WS--import qualified Waargonaut.Decode as D-import Waargonaut.Decode.Error (DecodeError)-import Waargonaut.Decode.Internal (CursorHistory' (..),- ZipperMove (..), compressHistory)-import qualified Waargonaut.Encode as E--import Waargonaut.Generic (mkDecoder, mkEncoder)+import qualified Waargonaut.Attoparsec as WA+import qualified Waargonaut.Decode as D+import qualified Waargonaut.Encode as E -import qualified Types.CommaSep as CS-import qualified Types.Common as Common-import qualified Types.Json as J-import qualified Types.Whitespace as WS+import qualified Types.Common as Common import qualified Decoder import qualified Decoder.Laws import qualified Encoder import qualified Encoder.Laws+import qualified Golden import qualified Json--encodeText- :: Json- -> Text-encodeText = TextL.toStrict- . TB.toLazyText- . W.waargonautBuilder WS.wsBuilder--decode- :: Text- -> Either DecodeError Json-decode =- Common.parseText--prop_history_condense :: Property-prop_history_condense = property $ do- n <- forAll $ Gen.int (Range.linear 1 10)- m <- forAll $ Gen.int (Range.linear 1 10)-- let- ixa = 1 :: Int- ixb = 2- mkCH = CursorHistory' . S.fromList- mcA cn cm n' m' = mkCH [(cn (n' ^. _Natural), ixa), (cm (m' ^. _Natural), ixb)]- mcB c x i = mkCH [(c (x ^. _Natural), i)]-- -- * [R n, R m] = [R (n + m)]- compressHistory (mcA R R n m) === mcB R (n + m) ixb-- -- * [L n, R m] = [L (n + m)]- compressHistory (mcA L L n m) === mcB L (n + m) ixb-- let- rlch = compressHistory (mcA R L n m)- lrch = compressHistory (mcA L R n m)- when (n > m) $ do- -- * [R n, L m] = [R (n - m)] where n > m- rlch === mcB R (n - m) ixa- -- * [L n, R m] = [L (n - m)] where n > m- lrch === mcB L (n - m) ixa-- when (n < m) $ do- -- * [R n, L m] = [L (m - n)] where n < m- rlch === mcB L (m - n) ixb- -- * [L n, R m] = [R (m - n)] where n < m- lrch === mcB R (m - n) ixb-- -- * [DAt k, R n] = [DAt k]- compressHistory (mkCH [(DAt "KeyName", ixa), (R (n ^. _Natural), ixb)]) === mkCH [(DAt "KeyName", ixa)]--prop_uncons_consCommaSep :: Property-prop_uncons_consCommaSep = property $ do- cs <- forAll $ CS.genCommaSeparated WS.genWS Gen.bool- let- elems = (^. CommaSep._CommaSeparated . _2)-- cs' = do- (e,xs) <- CommaSep.unconsCommaSep cs- let trailing = fromMaybe (CommaSep.Comma, mempty) (fst e)- elems $ CommaSep.consCommaSep (trailing, snd e) xs-- elems cs === cs'--prop_uncons_consCommaSepVal :: Property-prop_uncons_consCommaSepVal = property $ do- cs <- forAll $ CS.genCommaSeparated WS.genEmptyWS Gen.bool- let- elems = (^. CommaSep._CommaSeparated . _2)-- elems cs === (elems . uncurry L.cons =<< L.uncons cs)--prop_jchar :: Property-prop_jchar = property $ do- c <- forAll Gen.unicodeAll- tripping c toJChar (fmap fromJChar)- where- fromJChar :: JChar HeXDigit -> Char- fromJChar = (JChar._JChar #)-- toJChar :: Char -> Maybe (JChar HeXDigit)- toJChar = (^? JChar._JChar)--prop_jnumber_scientific_prism :: Property-prop_jnumber_scientific_prism = property $ do- sci <- forAll $ Sci.scientific- <$> Gen.integral (Range.linear 0 maxI)- <*> Gen.int Range.linearBounded-- tripping sci (JNumber._JNumberScientific #) (^? JNumber._JNumberScientific)- where- maxI :: Integer- maxI = 2 ^ (32 :: Integer)--simpleDecodeWith :: D.Decoder L.Identity a -> TextL.Text -> Either (DecodeError, D.CursorHistory) a-simpleDecodeWith d = D.simpleDecode d Common.parseBS . Text.encodeUtf8 . TextL.toStrict--prop_tripping_int_list :: Property-prop_tripping_int_list = property $ do- xs <- forAll . Gen.list (Range.linear 0 100) $ Gen.int (Range.linear 0 9999)- tripping xs- (E.simplePureEncodeNoSpaces (E.traversable E.int))- (simpleDecodeWith (D.list D.int))--prop_tripping_image_record_generic :: Property-prop_tripping_image_record_generic = withTests 1 . property $- Common.prop_generic_tripping mkEncoder mkDecoder Common.testImageDataType--prop_tripping_newtype_fudge_generic :: Property-prop_tripping_newtype_fudge_generic = withTests 1 . property $- Common.prop_generic_tripping mkEncoder mkDecoder Common.testFudge--prop_tripping_maybe_bool_generic :: Property-prop_tripping_maybe_bool_generic = property $- forAll (Gen.maybe Gen.bool) >>= Common.prop_generic_tripping mkEncoder mkDecoder--prop_tripping_int_list_generic :: Property-prop_tripping_int_list_generic = property $ do- xs <- forAll . Gen.list (Range.linear 0 100) $ Gen.int (Range.linear 0 9999)- Common.prop_generic_tripping mkEncoder mkDecoder xs--prop_tripping :: Property-prop_tripping = withTests 200 . property $- forAll J.genJson >>= (\j -> tripping j encodeText decode)--prop_print_parse_print_id :: Property-prop_print_parse_print_id = withTests 200 . property $ do- printedA <- forAll $ encodeText <$> J.genJson- Right printedA === (encodeText <$> decode printedA)--prop_maybe_maybe :: Property-prop_maybe_maybe = withTests 1 . property $ do- let- n = Nothing- jn = Just Nothing- jjt = Just (Just True)- jjf = Just (Just False)-- trippin' n- trippin' jn- trippin' jjt- trippin' jjf- where- trippin' a = tripping a- (E.simplePureEncodeNoSpaces enc)- (simpleDecodeWith dec)-- enc = E.maybeOrNull' . E.mapLikeObj' . E.atKey' "boop"- $ E.maybeOrNull' (E.mapLikeObj' (E.atKey' "beep" E.bool'))- -- $ E.mapLikeObj (E.atKey "beep" (E.maybeOrNull E.bool))-- dec = D.maybeOrNull $ D.atKey "boop"- $ D.maybeOrNull (D.atKey "beep" D.bool)- -- $ D.atKey "beep" (D.maybeOrNull D.bool)--tripping_properties :: TestTree-tripping_properties = testGroup "Properties"- [ testProperty "CommaSeparated: cons . uncons = id" prop_uncons_consCommaSep- , testProperty "CommaSeparated (disregard WS): cons . uncons = id" prop_uncons_consCommaSepVal- , testProperty "Char -> JChar Digit -> Maybe Char = Just id" prop_jchar- , testProperty "Scientific -> JNumber -> Maybe Scientific = Just id" prop_jnumber_scientific_prism- , testProperty "(Maybe (Maybe Bool))" prop_maybe_maybe- , testProperty "[Int]" prop_tripping_int_list- , testProperty "[Int] (generic)" prop_tripping_int_list_generic- , testProperty "Maybe Bool (generic)" prop_tripping_maybe_bool_generic- , testProperty "Image record (generic)" prop_tripping_image_record_generic- , testProperty "Newtype with Options (generic)" prop_tripping_newtype_fudge_generic- , testProperty "Condensing History" prop_history_condense- ]--parser_properties :: TestTree-parser_properties = testGroup "Parser Round-Trip"- [ testProperty "parse . print = id" prop_tripping- , testProperty "print . parse . print = print" prop_print_parse_print_id- ]--parsePrint :: Text -> Either DecodeError Text-parsePrint = fmap encodeText . decode--readTestFile :: FilePath -> IO Text-readTestFile fp = Text.readFile ("test/json-data" <> "/" <> fp)--testFile :: FilePath -> Assertion-testFile fp = do- s <- readTestFile fp- parsePrint s @?= Right s--testFileFailure :: FilePath -> Assertion-testFileFailure fp = do- s <- readTestFile fp- assertBool (fp <> " should fail to parse!") (isLeft $ parsePrint s)--unitTests :: TestTree-unitTests =- testGroup "File Tests - (print . parse = id)" (toTest <$> fs)- where- toTest f = testCase f (testFile f)-- fs =- [ "test1.json"- , "test2.json"- , "test3.json"- , "test5.json"- , "test7.json"- , "numbers.json"- ]+import qualified Properties mishandlingOfCharVsUtf8Bytes :: TestTree mishandlingOfCharVsUtf8Bytes = testCaseSteps "Mishandling of UTF-8 Bytes vs Haskell Char" $ \step -> do let valChar = '\128' :: Char valText = "\128" :: Text- valStr = [valChar] :: String+ valStr = [valChar] :: String encVal = "\"\128\"" :: Text- valUtf8Bytes = [34,194,128,34] :: [Word8]+ valBytes = [34,194,128,34] :: [Word8] + testFilePath = "test/json-data/mishandling.json"+ step "Pack String to Text" Text.pack valStr @?= valText step "Encoder via Text"- x <- TextL.toStrict <$> E.simpleEncodeNoSpaces E.text valText+ let x = TextL.toStrict $ Common.encodeText E.text valText x @?= encVal + step "Create JSON file"+ Text.writeFile testFilePath x+ step "encoder output ~ packed bytes"- Text.encodeUtf8 x @?= BS.pack valUtf8Bytes+ Text.encodeUtf8 x @?= BS.pack valBytes - step "Decoder via Text"- y <- D.runDecode D.text Common.parseBS (D.mkCursor (Text.encodeUtf8 x))- y @?= Right valText+ step "Decode file input"+ decodedFile <- WA.decodeAttoparsecText D.text =<< Text.readFile testFilePath+ decodedFile @?= Right valText regressionTests :: TestTree-regressionTests =- testGroup "Regression Tests - Failure to parse = Success" (toTestFail <$> fs)+regressionTests = testGroup "Expected Failure" $+ toTestFail <$> fs where- toTestFail (dsc, f) =- testCase dsc (testFileFailure f)+ toTestFail (dsc, f) = testCase dsc $ do+ r <- WA.decodeAttoparsecText D.json =<< Text.readFile ("test/json-data/bad-json/" <> f)+ assertBool (f <> " should fail to parse!") (isLeft r) fs =- [ ("[11 12 13] (test4.json)","test4.json")- , ("{\"foo\":3\"bar\":4} (test6.json)", "test6.json")+ [ ("[11 12 13] (test4.json)","no_comma_arr.json")+ , ("{\"foo\":3\"bar\":4} (test6.json)", "no_comma_obj.json") ] main :: IO ()-main = defaultMain $ testGroup "Waargonaut All Tests"- [ parser_properties- , tripping_properties- , unitTests- , regressionTests- , Json.jsonTests- , mishandlingOfCharVsUtf8Bytes+main = do+ goldens <- Golden.goldenTests+ defaultMain $ testGroup "Waargonaut All Tests"+ [ regressionTests+ , mishandlingOfCharVsUtf8Bytes - , Decoder.decoderTests- , Encoder.encoderTests+ , Properties.propertyTests+ , Json.jsonPrisms+ , Decoder.Laws.decoderLaws+ , Encoder.Laws.encoderLaws - , Decoder.Laws.decoderLaws- , Encoder.Laws.encoderLaws+ , Decoder.decoderTests+ , Encoder.encoderTests - , testGroup "text gen - text e/d"- [ testProperty "unicode" $ p Gen.text Gen.unicode E.text D.text- , testProperty "latin1" $ p Gen.text Gen.latin1 E.text D.text- , testProperty "ascii" $ p Gen.text Gen.ascii E.text D.text- ]- , testGroup "bytestring gen - via text e/d"- [ testProperty "unicode" $ p Gen.utf8 Gen.unicode bsE bsD- , testProperty "latin1" $ p Gen.utf8 Gen.latin1 bsE bsD- , testProperty "ascii" $ p Gen.utf8 Gen.ascii bsE bsD+ , goldens ]- ]- where- bsE = Text.decodeUtf8 >$< E.text- bsD = Text.encodeUtf8 <$> D.text-- p :: ( Eq a- , Show a- )- => (Range Int -> Gen Char -> Gen a)- -> Gen Char- -> E.Encoder' a- -> D.Decoder L.Identity a- -> Property- p f g e d = property $ do- inp <- forAll $ f (Range.linear 0 1000) g- tripping inp (E.simplePureEncodeNoSpaces e) (simpleDecodeWith d)
+ test/Properties.hs view
@@ -0,0 +1,281 @@+{-# LANGUAGE OverloadedStrings #-}+module Properties (propertyTests) where++import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Test.Tasty+import Test.Tasty.Hedgehog++import Control.Monad (when)++import Control.Lens ((^.), _2)+import qualified Control.Lens as L++import Data.Functor.Contravariant ((>$<))++import Data.Char (ord)+import Data.Maybe (fromMaybe)+import Natural (_Natural)++import qualified Data.Digit as Dig+import qualified Data.Scientific as Sci+import qualified Data.Sequence as S+import qualified Data.Text.Encoding as Text+import qualified Data.Text.Lazy as TL++import qualified Waargonaut.Attoparsec as WA++import qualified Waargonaut.Decode as D+import Waargonaut.Decode.Internal (CursorHistory' (..),+ ZipperMove (..),+ compressHistory)+import qualified Waargonaut.Encode as E+import Waargonaut.Generic (mkDecoder, mkEncoder)+import qualified Waargonaut.Types.CommaSep as CommaSep+import qualified Waargonaut.Types.JChar as JChar+import qualified Waargonaut.Types.JChar.HexDigit4 as Hex4+import qualified Waargonaut.Types.JNumber as JNumber++import qualified Types.CommaSep as CS+import qualified Types.Common as Common+import qualified Types.Json as J+import qualified Types.Whitespace as WS++propertyTests :: TestTree+propertyTests = testGroup "Property Tests"+ [ testProperty "CommaSeparated: cons . uncons = id" prop_uncons_consCommaSep+ , testProperty "CommaSeparated (disregard WS): cons . uncons = id" prop_uncons_consCommaSepVal+ , testProperty "Char -> JChar Digit -> Maybe Char = Just id" prop_jchar+ , testProperty "Scientific -> JNumber -> Maybe Scientific = Just id" prop_jnumber_scientific_prism+ , testProperty "(Maybe (Maybe Bool))" prop_maybe_maybe+ , testProperty "[Int]" prop_tripping_int_list+ , testProperty "[Int] (generic)" prop_tripping_int_list_generic+ , testProperty "Maybe Bool (generic)" prop_tripping_maybe_bool_generic+ , testProperty "Image record (generic)" prop_tripping_image_record_generic+ , testProperty "Newtype with Options (generic)" prop_tripping_newtype_fudge_generic+ , testProperty "Condensing History" prop_history_condense+ , testProperty "HexDigit4 conversion" prop_char_heXDigit+ , testProperty "HexDigit4 upper-case hex chars regression" prop_char_heXDigit_UpperCases+ , testProperty "Text & ByteString builders produce matching output" prop_builders_match+ , testProperty "parse . print = id" prop_tripping+ , testProperty "print . parse . print = print" prop_print_parse_print_id++ , testGroup "text gen - text encoder/decoder"+ [ testProperty "unicode" $ prop_text_enc Gen.unicode+ , testProperty "latin1" $ prop_text_enc Gen.latin1+ , testProperty "ascii" $ prop_text_enc Gen.ascii+ ]+ , testGroup "bytestring gen - via text encoder/decoder"+ [ testProperty "unicode" $ prop_bs_enc Gen.unicode+ , testProperty "latin1" $ prop_bs_enc Gen.latin1+ , testProperty "ascii" $ prop_bs_enc Gen.ascii+ ]+ ]++prop_bs_enc :: Gen Char -> Property+prop_bs_enc encType = trippingEncodingTest+ Gen.utf8+ encType+ (Text.decodeUtf8 >$< E.text)+ (Text.encodeUtf8 <$> D.text)++prop_text_enc :: Gen Char -> Property+prop_text_enc encType = trippingEncodingTest+ Gen.text+ encType+ E.text+ D.text+++trippingEncodingTest :: ( Eq a+ , Show a+ )+ => (Range Int -> Gen Char -> Gen a)+ -> Gen Char+ -> E.Encoder' a+ -> D.Decoder L.Identity a+ -> Property+trippingEncodingTest f g e d = property $ do+ inp <- forAll $ f (Range.linear 0 1000) g+ tripping inp (Common.encodeText e) (WA.pureDecodeAttoparsecText d . TL.toStrict)++charInAcceptableRange :: Char -> Bool+charInAcceptableRange c' = (ord c') >= 0x0 && (ord c') <= 0xffff++prop_char_heXDigit :: Property+prop_char_heXDigit = property $ do+ c <- forAll Gen.unicode++ let (anno, expect) = if charInAcceptableRange c+ then ("Char in valid range", Just c)+ else ("Char out of valid range", Nothing)++ annotate anno+ fmap Hex4.hexDigit4ToChar (Hex4.charToHexDigit4 c) === expect++prop_char_heXDigit_UpperCases :: Property+prop_char_heXDigit_UpperCases = property $ do+ c <- forAll $ Gen.filter charInAcceptableRange Gen.unicode++ let hex4 = Hex4.charToHexDigit4 c++ annotate "Generated Char should be in acceptable range!"+ hd <- maybe failure (pure . fmap ucHeX) hex4++ annotate "All upper-case hexdigits shouldn't affect conversion"+ Hex4.hexDigit4ToChar hd === c++ annotate "Conversion property should be maintained"+ fmap Hex4.hexDigit4ToChar hex4 === Just c+ where+ ucHeX Dig.HeXDigita = Dig.HeXDigitA+ ucHeX Dig.HeXDigitb = Dig.HeXDigitB+ ucHeX Dig.HeXDigitc = Dig.HeXDigitC+ ucHeX Dig.HeXDigitd = Dig.HeXDigitD+ ucHeX Dig.HeXDigite = Dig.HeXDigitE+ ucHeX Dig.HeXDigitf = Dig.HeXDigitF+ ucHeX d = d+++prop_history_condense :: Property+prop_history_condense = property $ do+ n <- forAll $ Gen.int (Range.linear 1 10)+ m <- forAll $ Gen.int (Range.linear 1 10)++ let+ ixa = 1 :: Int+ ixb = 2+ mkCH = CursorHistory' . S.fromList+ mcA cn cm n' m' = mkCH [(cn (n' ^. _Natural), ixa), (cm (m' ^. _Natural), ixb)]+ mcB c x i = mkCH [(c (x ^. _Natural), i)]++ -- * [R n, R m] = [R (n + m)]+ compressHistory (mcA R R n m) === mcB R (n + m) ixb++ -- * [L n, R m] = [L (n + m)]+ compressHistory (mcA L L n m) === mcB L (n + m) ixb++ let+ rlch = compressHistory (mcA R L n m)+ lrch = compressHistory (mcA L R n m)+ when (n > m) $ do+ -- * [R n, L m] = [R (n - m)] where n > m+ rlch === mcB R (n - m) ixa+ -- * [L n, R m] = [L (n - m)] where n > m+ lrch === mcB L (n - m) ixa++ when (n < m) $ do+ -- * [R n, L m] = [L (m - n)] where n < m+ rlch === mcB L (m - n) ixb+ -- * [L n, R m] = [R (m - n)] where n < m+ lrch === mcB R (m - n) ixb++ -- * [DAt k, R n] = [DAt k]+ compressHistory (mkCH [(DAt "KeyName", ixa), (R (n ^. _Natural), ixb)]) === mkCH [(DAt "KeyName", ixa)]++prop_uncons_consCommaSep :: Property+prop_uncons_consCommaSep = property $ do+ cs <- forAll $ CS.genCommaSeparated WS.genWS Gen.bool+ let+ elems = (^. CommaSep._CommaSeparated . _2)++ cs' = do+ (e,xs) <- CommaSep.unconsCommaSep cs+ let trailing = fromMaybe (CommaSep.Comma, mempty) (fst e)+ elems $ CommaSep.consCommaSep (trailing, snd e) xs++ elems cs === cs'++prop_uncons_consCommaSepVal :: Property+prop_uncons_consCommaSepVal = property $ do+ cs <- forAll $ CS.genCommaSeparated WS.genEmptyWS Gen.bool+ let+ elems = (^. CommaSep._CommaSeparated . _2)++ elems cs === (elems . uncurry L.cons =<< L.uncons cs)++prop_jchar :: Property+prop_jchar = property $ do+ c <- forAll Gen.unicodeAll+ tripping c JChar.charToJChar (fmap JChar.jCharToChar)++prop_jnumber_scientific_prism :: Property+prop_jnumber_scientific_prism = property $ do+ sci <- forAll $ Sci.scientific+ <$> Gen.integral (Range.linear 0 maxI)+ <*> Gen.int Range.linearBounded++ L.preview JNumber._JNumberScientific (L.review JNumber._JNumberScientific sci) === Just sci+ where+ maxI :: Integer+ maxI = 2 ^ (32 :: Integer)++prop_tripping_int_list :: Property+prop_tripping_int_list = property $ do+ xs <- forAll . Gen.list (Range.linear 0 100) $ Gen.int (Range.linear 0 9999)+ tripping xs+ (Common.encodeText (E.traversable E.int))+ (WA.pureDecodeAttoparsecText (D.list D.int) . TL.toStrict)++prop_tripping_image_record_generic :: Property+prop_tripping_image_record_generic = withTests 1 . property $+ Common.prop_generic_tripping mkEncoder mkDecoder Common.testImageDataType++prop_tripping_newtype_fudge_generic :: Property+prop_tripping_newtype_fudge_generic = withTests 1 . property $+ Common.prop_generic_tripping mkEncoder mkDecoder Common.testFudge++prop_tripping_maybe_bool_generic :: Property+prop_tripping_maybe_bool_generic = property $+ forAll (Gen.maybe Gen.bool) >>= Common.prop_generic_tripping mkEncoder mkDecoder++prop_tripping_int_list_generic :: Property+prop_tripping_int_list_generic = property $ do+ xs <- forAll . Gen.list (Range.linear 0 100) $ Gen.int (Range.linear 0 9999)+ Common.prop_generic_tripping mkEncoder mkDecoder xs++prop_tripping :: Property+prop_tripping = withTests 200 . property $+ forAll J.genJson >>= (\j -> tripping j Common.encodeJsonText (WA.pureDecodeAttoparsecText D.json))++prop_print_parse_print_id :: Property+prop_print_parse_print_id = withTests 200 . property $ do+ printedA <- forAll $ Common.encodeJsonText <$> J.genJson+ Right printedA === (Common.encodeJsonText <$> (WA.pureDecodeAttoparsecText D.json) printedA)++prop_builders_match :: Property+prop_builders_match = property $ do+ j <- forAll J.genJson++ let jt = Common.encodeJsonText j+ jb = Common.encodeBS j++ jt === Text.decodeUtf8 jb+ Text.encodeUtf8 jt === jb++prop_maybe_maybe :: Property+prop_maybe_maybe = withTests 1 . property $ do+ let+ n = Nothing+ jn = Just Nothing+ jjt = Just (Just True)+ jjf = Just (Just False)++ trippin' n+ trippin' jn+ trippin' jjt+ trippin' jjf+ where+ trippin' a = tripping a+ (Common.encodeText enc)+ (WA.pureDecodeAttoparsecText dec . TL.toStrict)++ enc = E.maybeOrNull' . E.mapLikeObj' . E.atKey' "boop"+ $ E.maybeOrNull' (E.mapLikeObj' (E.atKey' "beep" E.bool'))+ -- $ E.mapLikeObj (E.atKey "beep" (E.maybeOrNull E.bool))++ dec = D.maybeOrNull $ D.atKey "boop"+ $ D.maybeOrNull (D.atKey "beep" D.bool)+ -- $ D.atKey "beep" (D.maybeOrNull D.bool)
test/Types/Common.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} module Types.Common@@ -10,23 +11,22 @@ , genDecimalDigitNoZero , genHeXaDeCiMaLDigit , genHeXaDeCiMaLDigitNoZero- , genHexadecimalDigitLower , genNonEmptyDecimalDigit , genText+ , genScientific , genWhitespace- , hexadecimalDigitLower , prop_generic_tripping- , parseBS- , parseText+ , encodeJsonText+ , encodeText+ , encodeBS , testImageDataType , testFudge- , imageDecodeManual , imageDecodeGeneric , imageDecodeSuccinct - -- * Some test types to be messed with+ -- * Some test types to be messed with , Image (..) , Fudge (..) , HasImage (..)@@ -43,37 +43,35 @@ import qualified Data.List as List import Data.List.NonEmpty (NonEmpty) import Data.Maybe (fromMaybe)-import Data.Text (Text) -import qualified Data.Text.Encoding as Text-+import Data.Text (Text) import qualified Data.Text.Lazy as TextL import Hedgehog import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range +import Data.Scientific (Scientific)+import qualified Data.Scientific as Sci+ import Data.ByteString (ByteString) -import qualified Data.Attoparsec.ByteString as AB-import qualified Data.Attoparsec.Text as AT+import qualified Data.ByteString.Lazy as BL import Data.Tagged (Tagged) import qualified Data.Tagged as T -import Data.Digit (DecDigit, HeXDigit, HexDigit)+import Data.Digit (DecDigit, HeXDigit) import qualified Data.Digit as D -import Waargonaut (parseWaargonaut)-import qualified Waargonaut.Decode.Traversal as D- import qualified Waargonaut.Decode as SD -import Waargonaut.Decode.Error (DecodeError) import qualified Waargonaut.Encode as E import Waargonaut.Types (Json) import Waargonaut.Types.Whitespace (Whitespace (..)) +import qualified Waargonaut.Attoparsec as WA+ import Waargonaut.Generic (GWaarg, JsonDecode (..), JsonEncode (..), NewtypeName (..), Options (..), defaultOpts,@@ -104,17 +102,6 @@ <*> SD.fromKey "Animated" SD.bool io <*> SD.fromKey "IDs" (SD.list SD.int) io -imageDecodeManual :: Monad f => D.Decoder f Image-imageDecodeManual = D.withCursor $ \c -> do- io <- D.moveToKey "Image" c-- Image- <$> D.fromKey "Width" D.int io- <*> D.fromKey "Height" D.int io- <*> D.fromKey "Title" D.text io- <*> D.fromKey "Animated" D.bool io- <*> D.fromKey "IDs" (D.list D.int) io- imageDecodeGeneric :: Monad f => SD.Decoder f Image imageDecodeGeneric = SD.withCursor $ SD.fromKey "Image" iDec -- Without using 'Proxy' type, crunchy.@@ -172,9 +159,6 @@ genDecimalDigit :: Gen DecDigit genDecimalDigit = Gen.element decimalDigit -genHexadecimalDigitLower :: Gen HexDigit-genHexadecimalDigitLower = Gen.element hexadecimalDigitLower- genHeXaDeCiMaLDigit :: Gen HeXDigit genHeXaDeCiMaLDigit = Gen.element hExAdEcImAlDigit @@ -192,16 +176,6 @@ , D.DecDigit9 ] -hexadecimalDigitLower :: [HexDigit]-hexadecimalDigitLower =- [ D.HexDigita- , D.HexDigitb- , D.HexDigitc- , D.HexDigitd- , D.HexDigite- , D.HexDigitf- ]- hExAdEcImAlDigit :: [HeXDigit] hExAdEcImAlDigit = [ D.HeXDigit0@@ -252,12 +226,19 @@ genText :: Gen Text genText = Gen.text ( Range.linear 0 100 ) Gen.unicodeAll -parseBS :: ByteString -> Either DecodeError Json-parseBS = SD.parseWith AB.parseOnly parseWaargonaut+genScientific :: MonadGen m => Maybe Int -> m Scientific+genScientific lim = either fst fst . Sci.fromRationalRepetend lim+ <$> Gen.realFrac_ (Range.linearFrac 0.0001 1000.0) -parseText :: Text -> Either DecodeError Json-parseText = SD.parseWith AT.parseOnly parseWaargonaut+encodeJsonText :: Json -> Text+encodeJsonText = TextL.toStrict . E.simplePureEncodeText E.json +encodeText :: E.Encoder Identity a -> a -> TextL.Text+encodeText e = E.simplePureEncodeText e++encodeBS :: Json -> ByteString+encodeBS = BL.toStrict . E.simplePureEncodeByteString E.json+ prop_generic_tripping :: ( MonadTest m , Show a@@ -268,5 +249,5 @@ -> a -> m () prop_generic_tripping e d a = tripping a- (E.simplePureEncodeNoSpaces (T.untag e))- (SD.runPureDecode (T.untag d) parseBS . SD.mkCursor . Text.encodeUtf8 . TextL.toStrict)+ (E.simplePureEncodeTextNoSpaces (T.untag e))+ (WA.pureDecodeAttoparsecText (T.untag d) . TextL.toStrict)
test/Types/JChar.hs view
@@ -1,20 +1,23 @@ module Types.JChar ( genJChar , genHex4- , genHex4Lower+ , genJCharEscaped+ , genJCharUnescaped ) where import Hedgehog-import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Gen as Gen -import Control.Lens (preview)-import Types.Common (genHeXaDeCiMaLDigit, genHexadecimalDigitLower, genWhitespace)+import Control.Lens (preview)+import Types.Common (genHeXaDeCiMaLDigit,+ genWhitespace) -import Data.Digit (HeXDigit,HexDigit)+import Data.Digit (HeXDigit) -import Waargonaut.Types.JChar (HexDigit4 (..), JChar (..),- JCharEscaped (..), JCharUnescaped (..),- _JCharUnescaped)+import Waargonaut.Types.JChar (JChar (..))+import Waargonaut.Types.JChar.Escaped (Escaped (..))+import Waargonaut.Types.JChar.HexDigit4 (HexDigit4 (..))+import Waargonaut.Types.JChar.Unescaped (AsUnescaped (..), Unescaped) genJChar :: Gen (JChar HeXDigit) genJChar = Gen.choice@@ -22,10 +25,10 @@ , UnescapedJChar <$> genJCharUnescaped ] -genJCharUnescaped :: Gen JCharUnescaped-genJCharUnescaped = Gen.just $ preview _JCharUnescaped <$> Gen.unicode+genJCharUnescaped :: Gen Unescaped+genJCharUnescaped = Gen.just $ preview _Unescaped <$> Gen.unicode -genJCharEscaped :: Gen (JCharEscaped HeXDigit)+genJCharEscaped :: Gen (Escaped HeXDigit) genJCharEscaped = do h4 <- genHex4 ws <- genWhitespace@@ -44,10 +47,3 @@ <*> genHeXaDeCiMaLDigit <*> genHeXaDeCiMaLDigit <*> genHeXaDeCiMaLDigit--genHex4Lower :: Gen (HexDigit4 HexDigit)-genHex4Lower = HexDigit4- <$> genHexadecimalDigitLower- <*> genHexadecimalDigitLower- <*> genHexadecimalDigitLower- <*> genHexadecimalDigitLower
+ test/json-data/bad-json/no_comma_arr.json view
@@ -0,0 +1,1 @@+[11 12 13]
+ test/json-data/bad-json/no_comma_obj.json view
@@ -0,0 +1,1 @@+{"foo":3"bar":4}
+ test/json-data/goldens/backslash128.json.golden view
@@ -0,0 +1,1 @@+{"a":"\\128"}
+ test/json-data/goldens/empty_arr_empty_ws.json.golden view
@@ -0,0 +1,1 @@+[ ]
+ test/json-data/goldens/image_obj.json.golden view
@@ -0,0 +1,14 @@+{+ "Image": {+ "Width": 800,+ "Height": 600,+ "Title": "View from 15th Floor",+ "Thumbnail": {+ "Url": "http://www.example.com/image/481989943",+ "Height": 125,+ "Width": 100+ },+ "Animated" : false,+ "IDs": [116, 943, 234, 38793]+ }+}
+ test/json-data/goldens/location_array.json.golden view
@@ -0,0 +1,22 @@+[+ {+ "precision": "zip",+ "Latitude": 37.7668,+ "Longitude": -122.3959,+ "Address": "",+ "City": "SAN FRANCISCO",+ "State": "CA",+ "Zip": "94107",+ "Country": "US"+ },+ {+ "precision": "zip",+ "Latitude": 37.371991,+ "Longitude": -122.026020,+ "Address": "",+ "City": "SUNNYVALE",+ "State": "CA",+ "Zip": "94085",+ "Country": "US"+ }+]
+ test/json-data/goldens/nested_arrs.json.golden view
@@ -0,0 +1,1 @@+[[[[0.00]]]]
+ test/json-data/goldens/null_arr_trailing_comma_ws.json.golden view
@@ -0,0 +1,1 @@+[null, ]
+ test/json-data/goldens/numbers.json.golden view
@@ -0,0 +1,1 @@+[1.15, 1.3224999999999998, 1.5208749999999998, 1.7490062499999994, 2.0113571874999994, 2.313060765624999, 2.6600198804687487, 3.0590228625390607, 3.5178762919199196, 4.045557735707907, 4.652391396064092, 5.350250105473706, 6.152787621294761, 7.075705764488975, 8.137061629162321, 9.357620873536668, 10.761264004567169, 12.375453605252241, 14.231771646040077, 16.36653739294609, 18.821518001888, 21.644745702171196, 24.891457557496874, 28.625176191121405, 32.918952619789614, 37.856795512758055, 43.535314839671756, 50.06561206562252, 57.57545387546589, 66.21177195678577, 76.14353775030362, 87.56506841284916, 100.69982867477653, 115.804802975993, 133.17552342239193, 153.15185193575073, 176.1246297261133, 202.5433241850303, 232.9248228127848, 267.86354623470254, 308.04307816990786, 354.24953989539404, 407.3869708797031, 468.49501651165855, 538.7692689884072, 619.5846593366683, 712.5223582371685, 819.4007119727437, 942.3108187686552, 1083.6574415839534, 1246.2060578215462, 1433.136966494778, 1648.1075114689947, 1895.323638189344, 2179.622183917745, 2506.565511505407, 2882.5503382312177, 3314.9328889659, 3812.172822310785, 4383.998745657402, 5041.598557506012, 5797.838341131914, 6667.5140923017, 7667.641206146955, 8817.787387068996, 10140.455495129345, 11661.523819398746, 13410.752392308557, 15422.365251154839, 17735.720038828065, 20396.078044652273, 23455.489751350113, 26973.813214052625, 31019.885196160518, 35672.867975584595, 41023.79817192228, 47177.36789771062, 54253.97308236721, 62392.06904472228, 71750.87940143062, 82513.5113116452, 94890.53800839197, 109124.11870965076, 125492.73651609836, 144316.6469935131, 165964.14404254008, 190858.76564892105, 219487.5804962592, 252410.71757069806, 290272.32520630275, 333813.17398724816, 383885.1500853353, 441467.9225981356, 507688.1109878559, 583841.3276360342, 671417.5267814393, 772130.1557986551, 887949.6791684533, 1021142.1310437213, 1174313.4507002793, 1350460.4683053212, 1553029.5385511192, 1785983.969333787, 2053881.564733855, 2361963.7994439327, 2716258.369360523, 3123697.124764601, 3592251.6934792907, 4131089.447501184, 4750752.864626361, 5463365.794320315, 6282870.663468362, 7225301.262988616, 8309096.452436907, 9555460.920302443, 10988780.058347808, 12637097.067099977, 14532661.627164973, 16712560.871239718, 19219445.001925673, 22102361.752214525, 25417716.0150467, 29230373.417303704, 33614929.42989926, 38657168.84438414, 44455744.17104176, 51124105.79669802, 58792721.66620272, 67611629.91613312, 77753374.40355308, 89416380.56408603, 102828837.64869894, 118253163.29600377, 135991137.79040432, 156389808.45896497, 179848279.7278097, 206825521.68698114, 237849349.94002828, 273526752.4310325, 314555765.2956874, 361739130.09004045, 415999999.60354644, 478399999.5440784, 550159999.4756901, 632683999.3970436, 727586599.3066001, 836724589.20259, 962233277.5829784, 1106568269.2204251, 1272553509.6034887, 1463436536.044012, 1682952016.4506137, 1935394818.9182055, 2225704041.755936, 2559559648.019326, 2943493595.222225, 3385017634.5055585, 3892770279.681392, 4476685821.6336, 5148188694.87864, 5920416999.1104355, 6808479548.977001, 7829751481.32355, 9004214203.522081, 10354846334.050394, 11908073284.157951, 13694284276.781643, 15748426918.29889, 18110690956.04372, 20827294599.450275, 23951388789.367817, 27544097107.772987, 31675711673.938934, 36427068425.02977, 41891128688.78423, 48174797992.10186, 55401017690.91714, 63711170344.5547, 73267845896.2379, 84258022780.67358, 96896726197.77461, 111431235127.4408, 128145920396.5569, 147367808456.04044, 169472979724.44647, 194893926683.11343, 224128015685.58044, 257747218038.41748, 296409300744.1801, 340870695855.80707, 392001300234.1781, 450801495269.3048, 518421719559.70044, 596184977493.6555, 685612724117.7037, 788454632735.3593, 906722827645.6631, 1042731251792.5125, 1199140939561.3892, 1379012080495.5974, 1585863892569.937, 1823743476455.4275, 2097304997923.7415, 2411900747612.3022, 2773685859754.1475, 3189738738717.2695, 3668199549524.8594, 4218429481953.5884, 4851193904246.626, 5578872989883.619, 6415703938366.162, 7378059529121.086, 8484768458489.248, 9757483727262.635, 11221106286352.03, 12904272229304.832, 14839913063700.555, 17065900023255.637, 19625785026743.98, 22569652780755.58, 25955100697868.91, 29848365802549.246, 34325620672931.63, 39474463773871.375, 45395633339952.07, 52204978340944.88, 60035725092086.61, 69041083855899.59, 79397246434284.53, 91306833399427.2, 105002858409341.27, 120753287170742.45, 138866280246353.81, 159696222283306.88, 183650655625802.88, 211198253969673.3, 242877992065124.28, 279309690874892.9, 321206144506126.8, 369387066182045.8, 424795126109352.6, 488514395025755.5, 561791554279618.75, 646060287421561.5, 742969330534795.8, 854414730115015.0, 982576939632267.1, 1129963480577107.2, 1299458002663673.2, 1494376703063224.0, 1718533208522707.5, 1976313189801113.5, 2272760168271280.5, 2613674193511972.0, 3005725322538767.5, 3456584120919582.5, 3975071739057519.5, 4571332499916147.0, 5257032374903569.0, 6045587231139104.0, 6952425315809969.0, 7995289113181464.0, 9194582480158682.0, 1.0573769852182484e+16, 1.2159835330009856e+16, 1.3983810629511332e+16, 1.6081382223938032e+16, 1.8493589557528736e+16, 2.1267627991158044e+16, 2.4457772189831748e+16, 2.8126438018306508e+16, 3.234540372105248e+16, 3.719721427921035e+16, 4.27767964210919e+16, 4.919331588425568e+16, 5.657231326689403e+16, 6.505816025692813e+16, 7.481688429546734e+16, 8.603941693978744e+16, 9.894532948075555e+16, 1.1378712890286886e+17, 1.3085519823829918e+17, 1.5048347797404406e+17, 1.7305599967015066e+17, 1.9901439962067325e+17, 2.288665595637742e+17, 2.6319654349834032e+17, 3.026760250230913e+17, 3.48077428776555e+17, 4.002890430930382e+17, 4.603323995569939e+17, 5.29382259490543e+17, 6.087895984141244e+17, 7.00108038176243e+17, 8.051242439026793e+17, 9.258928804880812e+17, 1.0647768125612933e+18, 1.224493334445487e+18, 1.4081673346123103e+18, 1.6193924348041567e+18, 1.8623013000247798e+18, 2.1416464950284966e+18, 2.462893469282771e+18, 2.8323274896751867e+18, 3.257176613126464e+18, 3.7457531050954337e+18, 4.3076160708597484e+18, 4.95375848148871e+18, 5.696822253712016e+18, 6.551345591768818e+18, 7.53404743053414e+18, 8.66415454511426e+18, 9.963777726881399e+18, 1.1458344385913608e+19, 1.3177096043800648e+19, 1.5153660450370744e+19, 1.7426709517926355e+19, 2.0040715945615307e+19, 2.30468233374576e+19, 2.650384683807624e+19, 3.047942386378767e+19, 3.505133744335582e+19, 4.030903805985919e+19, 4.635539376883806e+19, 5.330870283416377e+19, 6.130500825928833e+19, 7.0500759498181575e+19, 8.10758734229088e+19, 9.323725443634512e+19, 1.0722284260179688e+20, 1.233062689920664e+20, 1.4180220934087634e+20, 1.6307254074200778e+20, 1.8753342185330894e+20, 2.1566343513130526e+20, 2.4801295040100103e+20, 2.8521489296115116e+20, 3.2799712690532385e+20, 3.7719669594112236e+20, 4.337762003322907e+20, 4.988426303821342e+20, 5.7366902493945437e+20, 6.597193786803724e+20, 7.586772854824282e+20, 8.724788783047925e+20, 1.0033507100505113e+21, 1.1538533165580878e+21, 1.326931314041801e+21, 1.5259710111480708e+21, 1.7548666628202813e+21, 2.0180966622433234e+21, 2.3208111615798217e+21, 2.668932835816795e+21, 3.0692727611893135e+21, 3.529663675367711e+21, 4.059113226672867e+21, 4.667980210673796e+21, 5.368177242274866e+21, 6.173403828616095e+21, 7.099414402908508e+21, 8.164326563344784e+21, 9.388975547846502e+21, 1.0797321880023475e+22, 1.2416920162026996e+22, 1.4279458186331043e+22, 1.64213769142807e+22, 1.8884583451422802e+22, 2.171727096913622e+22, 2.497486161450665e+22, 2.872109085668265e+22, 3.3029254485185042e+22, 3.798364265796279e+22, 4.368118905665721e+22, 5.0233367415155795e+22, 5.7768372527429155e+22, 6.643362840654352e+22, 7.639867266752504e+22, 8.78584735676538e+22, 1.0103724460280185e+23, 1.1619283129322213e+23, 1.3362175598720545e+23, 1.5366501938528623e+23, 1.7671477229307915e+23, 2.0322198813704103e+23, 2.3370528635759717e+23, 2.687610793112367e+23, 3.090752412079222e+23, 3.554365273891105e+23, 4.0875200649747705e+23, 4.700648074720986e+23, 5.405745285929133e+23, 6.216607078818502e+23, 7.149098140641278e+23, 8.221462861737468e+23, 9.454682290998088e+23, 1.0872884634647801e+24, 1.250381732984497e+24, 1.4379389929321714e+24, 1.653629841871997e+24, 1.9016743181527962e+24, 2.1869254658757156e+24, 2.5149642857570727e+24, 2.8922089286206334e+24, 3.326040267913728e+24, 3.824946308100787e+24, 4.3986882543159046e+24, 5.05849149246329e+24, 5.817265216332783e+24, 6.6898549987827e+24, 7.693333248600105e+24, 8.84733323589012e+24, 1.0174433221273637e+25, 1.1700598204464681e+25, 1.3455687935134384e+25, 1.547404112540454e+25, 1.779514729421522e+25, 2.04644193883475e+25, 2.353408229659962e+25, 2.7064194641089563e+25, 3.1123823837253e+25, 3.5792397412840944e+25, 4.116125702476708e+25, 4.733544557848214e+25, 5.443576241525446e+25, 6.260112677754262e+25, 7.199129579417401e+25, 8.27899901633001e+25, 9.52084886877951e+25, 1.0948976199096437e+26, 1.25913226289609e+26, 1.4480021023305035e+26, 1.665202417680079e+26, 1.9149827803320907e+26, 2.202230197381904e+26, 2.5325647269891895e+26, 2.9124494360375676e+26, 3.349316851443203e+26, 3.8517143791596826e+26, 4.429471536033635e+26, 5.09389226643868e+26, 5.857976106404481e+26, 6.736672522365153e+26, 7.747173400719924e+26, 8.909249410827912e+26, 1.0245636822452099e+27, 1.1782482345819913e+27, 1.35498546976929e+27, 1.5582332902346833e+27, 1.7919682837698857e+27, 2.0607635263353683e+27, 2.3698780552856732e+27, 2.725359763578524e+27, 3.1341637281153025e+27, 3.6042882873325974e+27, 4.1449315304324867e+27, 4.7666712599973594e+27, 5.481671948996963e+27, 6.303922741346507e+27, 7.249511152548482e+27, 8.336937825430755e+27, 9.587478499245366e+27, 1.102560027413217e+28, 1.2679440315251995e+28, 1.4581356362539794e+28, 1.6768559816920761e+28, 1.9283843789458875e+28, 2.2176420357877703e+28, 2.5502883411559357e+28, 2.932831592329326e+28, 3.3727563311787245e+28, 3.8786697808555327e+28, 4.460470247983863e+28, 5.129540785181441e+28, 5.8989719029586575e+28, 6.783817688402455e+28, 7.801390341662823e+28, 8.971598892912247e+28, 1.0317338726849081e+29, 1.1864939535876443e+29, 1.3644680466257909e+29, 1.5691382536196593e+29, 1.8045089916626083e+29, 2.0751853404119993e+29, 2.3864631414737988e+29, 2.7444326126948684e+29, 3.1560975045990984e+29, 3.629512130288963e+29, 4.173938949832307e+29, 4.800029792307153e+29, 5.520034261153225e+29, 6.348039400326208e+29, 7.300245310375139e+29, 8.39528210693141e+29, 9.65457442297112e+29, 1.1102760586416787e+30, 1.2768174674379305e+30, 1.46834008755362e+30, 1.6885911006866628e+30, 1.941879765789662e+30, 2.2331617306581113e+30, 2.568135990256828e+30, 2.9533563887953516e+30, 3.396359847114654e+30, 3.905813824181852e+30, 4.491685897809129e+30, 5.165438782480498e+30, 5.940254599852573e+30, 6.831292789830458e+30, 7.855986708305026e+30, 9.034384714550779e+30, 1.0389542421733396e+31, 1.1947973784993405e+31, 1.3740169852742412e+31, 1.5801195330653773e+31, 1.817137463025184e+31, 2.0897080824789613e+31, 2.4031642948508052e+31, 2.7636389390784257e+31, 3.1781847799401893e+31, 3.6549124969312175e+31, 4.2031493714709e+31, 4.833621777191535e+31, 5.558665043770264e+31, 6.392464800335803e+31, 7.3513345203861735e+31, 8.454034698444098e+31, 9.722139903210713e+31, 1.1180460888692319e+32, 1.2857530021996165e+32, 1.478615952529559e+32, 1.7004083454089925e+32, 1.9554695972203414e+32, 2.2487900368033926e+32, 2.586108542323901e+32, 2.974024823672486e+32, 3.420128547223359e+32, 3.933147829306862e+32, 4.523120003702891e+32, 5.2015880042583246e+32, 5.981826204897073e+32, 6.879100135631634e+32, 7.910965155976377e+32, 9.097609929372833e+32, 1.0462251418778757e+33, 1.2031589131595571e+33, 1.3836327501334904e+33, 1.591177662653514e+33, 1.8298543120515409e+33, 2.104332458859272e+33, 2.4199823276881623e+33, 2.7829796768413863e+33, 3.200426628367594e+33, 3.6804906226227334e+33, 4.232564216016143e+33, 4.867448848418564e+33, 5.597566175681348e+33, 6.437201102033549e+33, 7.402781267338582e+33, 8.513198457439368e+33, 9.790178226055273e+33, 1.1258704959963564e+34, 1.2947510703958096e+34, 1.488963730955181e+34, 1.712308290598458e+34, 1.9691545341882266e+34, 2.2645277143164603e+34, 2.604206871463929e+34, 2.994837902183518e+34, 3.4440635875110457e+34, 3.960673125637702e+34, 4.554774094483357e+34, 5.237990208655861e+34, 6.023688739954239e+34, 6.927242050947375e+34, 7.96632835858948e+34, 9.161277612377902e+34, 1.0535469254234585e+35, 1.2115789642369772e+35, 1.3933158088725236e+35, 1.6023131802034022e+35, 1.8426601572339122e+35, 2.119059180818999e+35, 2.4369180579418488e+35, 2.8024557666331258e+35, 3.2228241316280944e+35, 3.706247751372308e+35, 4.262184914078154e+35, 4.901512651189877e+35, 5.636739548868358e+35, 6.482250481198611e+35, 7.454588053378403e+35, 8.572776261385162e+35, 9.858692700592935e+35, 1.1337496605681875e+36, 1.3038121096534156e+36, 1.499383926101428e+36, 1.7242915150166418e+36, 1.982935242269138e+36, 2.2803755286095084e+36]
+ test/json-data/goldens/twitter100.json.golden view
@@ -0,0 +1,1 @@+{"results":[{"from_user_id_str":"3646730","profile_image_url":"http://a3.twimg.com/profile_images/404973767/avatar_normal.jpg","created_at":"Wed, 26 Jan 2011 04:35:07 +0000","from_user":"nicolaslara","id_str":"30121530767708160","metadata":{"result_type":"recent"},"to_user_id":18616016,"text":"@josej30 Python y Clojure. Obviamente son diferentes, y cada uno tiene sus ventajas y desventajas. De Haskell faltar\u00eda pattern matching","id":30121530767708160,"from_user_id":3646730,"to_user":"josej30","geo":null,"iso_language_code":"es","to_user_id_str":"18616016","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"207858021","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Wed, 26 Jan 2011 04:30:38 +0000","from_user":"pboudarga","id_str":"30120402839666689","metadata":{"result_type":"recent"},"to_user_id":null,"text":"I'm at Rolla Sushi Grill (27737 Bouquet Canyon Road, #106, Btw Haskell Canyon and Rosedell Drive, Saugus) http://4sq.com/gqqdhs","id":30120402839666689,"from_user_id":207858021,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://foursquare.com" rel="nofollow">foursquare</a>"},{"from_user_id_str":"69988683","profile_image_url":"http://a0.twimg.com/profile_images/1211955817/avatar_7888_normal.gif","created_at":"Wed, 26 Jan 2011 04:25:23 +0000","from_user":"YNK33","id_str":"30119083059978240","metadata":{"result_type":"recent"},"to_user_id":null,"text":"hsndfile 0.5.0: Free and open source Haskell bindings for libsndfile http://bit.ly/gHaBWG Mac Os","id":30119083059978240,"from_user_id":69988683,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"81492","profile_image_url":"http://a1.twimg.com/profile_images/423894208/Picture_7_normal.jpg","created_at":"Wed, 26 Jan 2011 04:24:28 +0000","from_user":"satzz","id_str":"30118851488251904","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Emacs\u306e\u30e2\u30fc\u30c9\u8868\u793a\u304c\u4eca(Ruby Controller Outputz RoR Flymake REl hs)\u3068\u306a\u3063\u3066\u3066\u3088\u304f\u308f\u304b\u3089\u306a\u3044\u3093\u3060\u3051\u3069\u6700\u5f8c\u306eREl\u3068\u304bhs\u3063\u3066\u4f55\u3060\u308d\u3046\u2026haskell\u3068\u304b2\u5e74\u4ee5\u4e0a\u66f8\u3044\u3066\u306a\u3044\u3051\u3069\u2026","id":30118851488251904,"from_user_id":81492,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"9518356","profile_image_url":"http://a2.twimg.com/profile_images/119165723/ocaml-icon_normal.png","created_at":"Wed, 26 Jan 2011 04:19:19 +0000","from_user":"planet_ocaml","id_str":"30117557788741632","metadata":{"result_type":"recent"},"to_user_id":null,"text":"I so miss #haskell type classes in #ocaml - i want to do something like refinement. Also why does ocaml not have... http://bit.ly/geYRwt","id":30117557788741632,"from_user_id":9518356,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"218059","profile_image_url":"http://a1.twimg.com/profile_images/1053837723/twitter-icon9_normal.jpg","created_at":"Wed, 26 Jan 2011 04:16:32 +0000","from_user":"aprikip","id_str":"30116854940835840","metadata":{"result_type":"recent"},"to_user_id":null,"text":"yatex-mode\u3084haskell-mode\u306e\u3053\u3068\u3067\u3059\u306d\u3001\u308f\u304b\u308a\u307e\u3059\u3002","id":30116854940835840,"from_user_id":218059,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>"},{"from_user_id_str":"216363","profile_image_url":"http://a1.twimg.com/profile_images/72454310/Tim-Avatar_normal.png","created_at":"Wed, 26 Jan 2011 04:15:30 +0000","from_user":"dysinger","id_str":"30116594684264448","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell in Hawaii tonight for me... #fun","id":30116594684264448,"from_user_id":216363,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.nambu.com/" rel="nofollow">Nambu</a>"},{"from_user_id_str":"1774820","profile_image_url":"http://a2.twimg.com/profile_images/61169291/dan_desert_thumb_normal.jpg","created_at":"Wed, 26 Jan 2011 04:13:36 +0000","from_user":"DanMil","id_str":"30116117682851840","metadata":{"result_type":"recent"},"to_user_id":1594784,"text":"@ojrac @chewedwire @tomheon Haskell isn't a language, it's a belief system. A seductive one...","id":30116117682851840,"from_user_id":1774820,"to_user":"ojrac","geo":null,"iso_language_code":"en","to_user_id_str":"1594784","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"659256","profile_image_url":"http://a0.twimg.com/profile_images/746976711/angular-final_normal.jpg","created_at":"Wed, 26 Jan 2011 04:11:06 +0000","from_user":"djspiewak","id_str":"30115488931520512","metadata":{"result_type":"recent"},"to_user_id":null,"text":"One of the very nice things about Haskell as opposed to SML is the reduced proliferation of identifiers (e.g. andb, orb, etc). #typeclasses","id":30115488931520512,"from_user_id":659256,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"144546280","profile_image_url":"http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png","created_at":"Wed, 26 Jan 2011 04:06:12 +0000","from_user":"listwarenet","id_str":"30114255890026496","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://www.listware.net/201101/haskell-cafe/84752-re-haskell-cafe-gpl-license-of-h-matrix-and-prelude-numeric.html Re: Haskell-c","id":30114255890026496,"from_user_id":144546280,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>"},{"from_user_id_str":"1594784","profile_image_url":"http://a2.twimg.com/profile_images/378515773/square-profile_normal.jpg","created_at":"Wed, 26 Jan 2011 04:01:29 +0000","from_user":"ojrac","id_str":"30113067333324800","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @tomheon: @ojrac @chewedwire Don't worry, learning Haskell will not give you any clear idea what monad means.","id":30113067333324800,"from_user_id":1594784,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"207589736","profile_image_url":"http://a3.twimg.com/profile_images/1225527428/headshot_1_normal.jpg","created_at":"Wed, 26 Jan 2011 04:00:13 +0000","from_user":"ashleevelazq101","id_str":"30112747555397632","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Federal investigation finds safety violations at The Acadia Hospital: By Meg Haskell, BDN Staff The investigatio... http://bit.ly/dONnpn","id":30112747555397632,"from_user_id":207589736,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"17671137","profile_image_url":"http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png","created_at":"Wed, 26 Jan 2011 03:58:00 +0000","from_user":"Hackage","id_str":"30112192346984448","metadata":{"result_type":"recent"},"to_user_id":null,"text":"streams 0.4, added by EdwardKmett: Various Haskell 2010 stream comonads http://bit.ly/idBkPe","id":30112192346984448,"from_user_id":17671137,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"17489366","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Wed, 26 Jan 2011 03:58:00 +0000","from_user":"aapnoot","id_str":"30112191881420800","metadata":{"result_type":"recent"},"to_user_id":null,"text":"streams 0.4, added by EdwardKmett: Various Haskell 2010 stream comonads http://bit.ly/idBkPe","id":30112191881420800,"from_user_id":17489366,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"8530482","profile_image_url":"http://a2.twimg.com/profile_images/137867266/n608671563_7396_normal.jpg","created_at":"Wed, 26 Jan 2011 03:50:12 +0000","from_user":"jeffmclamb","id_str":"30110229207187456","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Angel - daemon to run and monitor processes like daemontools or god, written in Haskell http://ff.im/-wNyLk","id":30110229207187456,"from_user_id":8530482,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://friendfeed.com" rel="nofollow">FriendFeed</a>"},{"from_user_id_str":"177539201","profile_image_url":"http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg","created_at":"Wed, 26 Jan 2011 03:46:01 +0000","from_user":"tomheon","id_str":"30109174645919744","metadata":{"result_type":"recent"},"to_user_id":1594784,"text":"@ojrac @chewedwire Don't worry, learning Haskell will not give you any clear idea what monad means.","id":30109174645919744,"from_user_id":177539201,"to_user":"ojrac","geo":null,"iso_language_code":"en","to_user_id_str":"1594784","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"1594784","profile_image_url":"http://a2.twimg.com/profile_images/378515773/square-profile_normal.jpg","created_at":"Wed, 26 Jan 2011 03:44:34 +0000","from_user":"ojrac","id_str":"30108808684503040","metadata":{"result_type":"recent"},"to_user_id":128028225,"text":"@chewedwire @tomheon Why are you making me curious about Haskell? I LIKE not knowing what monad means!!","id":30108808684503040,"from_user_id":1594784,"to_user":"chewedwire","geo":null,"iso_language_code":"en","to_user_id_str":"128028225","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"23750094","profile_image_url":"http://a0.twimg.com/profile_images/951373780/Moeinthecar_normal.jpg","created_at":"Wed, 26 Jan 2011 03:41:54 +0000","from_user":"shokalshab","id_str":"30108140443795456","metadata":{"result_type":"recent"},"to_user_id":null,"text":"I'm at Magnitude Cheer @ Gymnastics Olympica USA (7735 Haskell Ave., btw Saticoy & Strathern, Van Nuys) http://4sq.com/gmXfaL","id":30108140443795456,"from_user_id":23750094,"geo":null,"iso_language_code":"en","place":{"id":"4e4a2a2f86cb2946","type_":"poi","full_name":"Gymnastics Olympica USA, Van Nuys"},"to_user_id_str":null,"source":"<a href="http://foursquare.com" rel="nofollow">foursquare</a>"},{"from_user_id_str":"8135112","profile_image_url":"http://a0.twimg.com/profile_images/1165240350/LIMITED_normal.jpg","created_at":"Wed, 26 Jan 2011 03:41:35 +0000","from_user":"Claricei","id_str":"30108059208515584","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @kristenmchugh22: @KeithOlbermann Ryan looks like Jughead w/o the hat. And sounds as mealy-mouthed as Eddie Haskell.","id":30108059208515584,"from_user_id":8135112,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"128028225","profile_image_url":"http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg","created_at":"Wed, 26 Jan 2011 03:40:02 +0000","from_user":"chewedwire","id_str":"30107670367182848","metadata":{"result_type":"recent"},"to_user_id":177539201,"text":"@tomheon Cool, I'll take a look. I feel like I should mention this: http://bit.ly/hVstDM","id":30107670367182848,"from_user_id":128028225,"to_user":"tomheon","geo":null,"iso_language_code":"en","to_user_id_str":"177539201","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"8679778","profile_image_url":"http://a3.twimg.com/profile_images/1195318056/me_nyc_12_18_10_icon_normal.jpg","created_at":"Wed, 26 Jan 2011 03:38:42 +0000","from_user":"kristenmchugh22","id_str":"30107332381777920","metadata":{"result_type":"recent"},"to_user_id":756269,"text":"@KeithOlbermann Ryan looks like Jughead w/o the hat. And sounds as mealy-mouthed as Eddie Haskell.","id":30107332381777920,"from_user_id":8679778,"to_user":"KeithOlbermann","geo":null,"iso_language_code":"en","to_user_id_str":"756269","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"103316559","profile_image_url":"http://a1.twimg.com/profile_images/1179458751/bc3beab4-d59d-4e78-b13b-50747986cfa2_normal.png","created_at":"Wed, 26 Jan 2011 03:36:15 +0000","from_user":"cityslikr","id_str":"30106719153557504","metadata":{"result_type":"recent"},"to_user_id":null,"text":""Social safety net into a hammock." So says Eddie Haskell with the GOP response. #SOTU","id":30106719153557504,"from_user_id":103316559,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://blackberry.com/twitter" rel="nofollow">Twitter for BlackBerry\u00ae</a>"},{"from_user_id_str":"169063143","profile_image_url":"http://a0.twimg.com/profile_images/1160506212/9697_1_normal.gif","created_at":"Wed, 26 Jan 2011 03:31:52 +0000","from_user":"wrkforce_safety","id_str":"30105614919143424","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Federal investigation finds safety violations at The Acadia Hospital: By Meg Haskell, BDN Staff The investigatio... http://bit.ly/gA60C1","id":30105614919143424,"from_user_id":169063143,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"177539201","profile_image_url":"http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg","created_at":"Wed, 26 Jan 2011 03:29:40 +0000","from_user":"tomheon","id_str":"30105060960632832","metadata":{"result_type":"recent"},"to_user_id":128028225,"text":"@chewedwire Great book on Haskell: http://oreilly.com/catalog/9780596514983","id":30105060960632832,"from_user_id":177539201,"to_user":"chewedwire","geo":null,"iso_language_code":"en","to_user_id_str":"128028225","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"782692","profile_image_url":"http://a0.twimg.com/profile_images/1031304589/Profile.2007.1_normal.jpg","created_at":"Wed, 26 Jan 2011 03:29:19 +0000","from_user":"turnageb","id_str":"30104974591533057","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @ovillalon: Paul Ryan solves the mystery of whatever happened to Eddie Haskell. #sotu","id":30104974591533057,"from_user_id":782692,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"128028225","profile_image_url":"http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg","created_at":"Wed, 26 Jan 2011 03:28:04 +0000","from_user":"chewedwire","id_str":"30104657267265536","metadata":{"result_type":"recent"},"to_user_id":177539201,"text":"@tomheon I always loved the pattern matching in SML and it looks like Haskell is MUCH better at it. I'm messing around now at tryhaskell.org","id":30104657267265536,"from_user_id":128028225,"to_user":"tomheon","geo":null,"iso_language_code":"en","to_user_id_str":"177539201","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"12834082","profile_image_url":"http://a3.twimg.com/profile_images/1083036140/mugshot_normal.png","created_at":"Wed, 26 Jan 2011 03:28:01 +0000","from_user":"ovillalon","id_str":"30104647213518848","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Paul Ryan solves the mystery of whatever happened to Eddie Haskell. #sotu","id":30104647213518848,"from_user_id":12834082,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"13540930","profile_image_url":"http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg","created_at":"Wed, 26 Jan 2011 03:26:02 +0000","from_user":"goodfox","id_str":"30104146455560192","metadata":{"result_type":"recent"},"to_user_id":10226179,"text":"@billykeene22 Bordeaux is one of my heroes. I was so excited when he accepted the invitation to campus. He's been a great friend to Haskell.","id":30104146455560192,"from_user_id":13540930,"to_user":"billykeene22","geo":null,"iso_language_code":"en","to_user_id_str":"10226179","source":"<a href="http://www.ubertwitter.com/bb/download.php" rel="nofollow">\u00dcberTwitter</a>"},{"from_user_id_str":"18616016","profile_image_url":"http://a2.twimg.com/profile_images/1173522726/214397343_normal.jpg","created_at":"Wed, 26 Jan 2011 03:25:18 +0000","from_user":"josej30","id_str":"30103962313031681","metadata":{"result_type":"recent"},"to_user_id":14870909,"text":"@cris7ian Ahh bueno multiparadigma ya es respetable :) Empezar\u00e9 a explotar la parte funcional de los lenguajes ahora #Haskell","id":30103962313031681,"from_user_id":18616016,"to_user":"Cris7ian","geo":null,"iso_language_code":"es","to_user_id_str":"14870909","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"14870909","profile_image_url":"http://a2.twimg.com/profile_images/1176930429/oso_yo_normal.png","created_at":"Wed, 26 Jan 2011 03:23:43 +0000","from_user":"Cris7ian","id_str":"30103562360983553","metadata":{"result_type":"recent"},"to_user_id":18616016,"text":"@josej30 hahaha no, es multiparadigma y es bastante lazy. Nothing like haskell, pero s\u00ed, el de Flash","id":30103562360983553,"from_user_id":14870909,"to_user":"josej30","geo":null,"iso_language_code":"es","to_user_id_str":"18616016","source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"2421643","profile_image_url":"http://a0.twimg.com/profile_images/1190361665/ernestgrumbles-17_normal.jpg","created_at":"Wed, 26 Jan 2011 03:20:24 +0000","from_user":"ernestgrumbles","id_str":"30102730756333568","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Wow... WolframAlpha did not know who Eddie Haskell is. Guess I'll never use that "knowledge engine" again.","id":30102730756333568,"from_user_id":2421643,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"128028225","profile_image_url":"http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg","created_at":"Wed, 26 Jan 2011 03:14:21 +0000","from_user":"chewedwire","id_str":"30101204428132352","metadata":{"result_type":"recent"},"to_user_id":177539201,"text":"@tomheon How is Haskell better/different from CL or Scheme? I honestly don't know, although I'm becoming more curious.","id":30101204428132352,"from_user_id":128028225,"to_user":"tomheon","geo":null,"iso_language_code":"en","to_user_id_str":"177539201","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"13540930","profile_image_url":"http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg","created_at":"Wed, 26 Jan 2011 03:06:54 +0000","from_user":"goodfox","id_str":"30099329809129473","metadata":{"result_type":"recent"},"to_user_id":null,"text":"A day of vision & speeches. #SOTU now. And a wonderful Haskell Convocation address earlier today by Sinte Gleske President Lionel Bordeaux.","id":30099329809129473,"from_user_id":13540930,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.ubertwitter.com/bb/download.php" rel="nofollow">\u00dcberTwitter</a>"},{"from_user_id_str":"119185220","profile_image_url":"http://a0.twimg.com/profile_images/1089027228/dfg_normal.jpg","created_at":"Wed, 26 Jan 2011 03:03:38 +0000","from_user":"LaLiciouz_03","id_str":"30098510623805440","metadata":{"result_type":"recent"},"to_user_id":null,"text":"The Game with the girl room 330 Haskell follow us...","id":30098510623805440,"from_user_id":119185220,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"18616016","profile_image_url":"http://a2.twimg.com/profile_images/1173522726/214397343_normal.jpg","created_at":"Wed, 26 Jan 2011 02:57:25 +0000","from_user":"josej30","id_str":"30096946144215040","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Voy a extra\u00f1ar Haskell cuando regrese al mundo imperativo. Hay alg\u00fan lenguaje imperativo que tenga este poder funcional? #ci3661","id":30096946144215040,"from_user_id":18616016,"geo":null,"iso_language_code":"es","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"17671137","profile_image_url":"http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png","created_at":"Wed, 26 Jan 2011 02:55:32 +0000","from_user":"Hackage","id_str":"30096471814574080","metadata":{"result_type":"recent"},"to_user_id":null,"text":"comonad-transformers 0.9.0, added by EdwardKmett: Haskell 98 comonad transformers http://bit.ly/h6xIsf","id":30096471814574080,"from_user_id":17671137,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"177539201","profile_image_url":"http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg","created_at":"Wed, 26 Jan 2011 02:48:12 +0000","from_user":"tomheon","id_str":"30094626920603649","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Every time I look at Haskell I love it more.","id":30094626920603649,"from_user_id":177539201,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"60792568","profile_image_url":"http://a0.twimg.com/profile_images/1203647517/glenda-flash_normal.jpg","created_at":"Wed, 26 Jan 2011 02:40:42 +0000","from_user":"r_takaishi","id_str":"30092735935422464","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell\u3088\u308aD\u8a00\u8a9e\u304c\u4e0a\u3068\u306f\u601d\u308f\u306a\u304b\u3063\u305f\uff0e http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html","id":30092735935422464,"from_user_id":60792568,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twmode.sf.net/" rel="nofollow">twmode</a>"},{"from_user_id_str":"160145510","profile_image_url":"http://a0.twimg.com/profile_images/1218108166/going_galt_normal.jpg","created_at":"Wed, 26 Jan 2011 02:39:31 +0000","from_user":"wtp1787","id_str":"30092439653974018","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @KLSouth: Eddie Haskell Goes to Washington... "You look really nice tonight, Ms Cleaver"","id":30092439653974018,"from_user_id":160145510,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"96616016","profile_image_url":"http://a1.twimg.com/profile_images/1196978169/Picture0002_normal.jpg","created_at":"Wed, 26 Jan 2011 02:39:20 +0000","from_user":"MelissaRNMBA","id_str":"30092392203816960","metadata":{"result_type":"recent"},"to_user_id":14862975,"text":"@KLSouth At least Eddie Haskell was entertaining.","id":30092392203816960,"from_user_id":96616016,"to_user":"KLSouth","geo":null,"iso_language_code":"en","to_user_id_str":"14862975","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"14862975","profile_image_url":"http://a0.twimg.com/profile_images/421596393/kls_4_normal.JPG","created_at":"Wed, 26 Jan 2011 02:38:29 +0000","from_user":"KLSouth","id_str":"30092178327871489","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Eddie Haskell Goes to Washington... "You look really nice tonight, Ms Cleaver"","id":30092178327871489,"from_user_id":14862975,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"144546280","profile_image_url":"http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png","created_at":"Wed, 26 Jan 2011 02:36:17 +0000","from_user":"listwarenet","id_str":"30091626869161984","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://www.listware.net/201101/haskell-beginners/84641-haskell-beginners-wildcards-in-expressions.html Haskell-beginners - Wild","id":30091626869161984,"from_user_id":144546280,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>"},{"from_user_id_str":"24538048","profile_image_url":"http://a2.twimg.com/profile_images/1117267605/rope_normal.jpg","created_at":"Wed, 26 Jan 2011 02:23:14 +0000","from_user":"dbph","id_str":"30088341030440960","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @dnene: Skilled Calisthenics. Haskell code that outputs python which spits ruby which emits the haskell source. http://j.mp/YlQUL via @mfeathers","id":30088341030440960,"from_user_id":24538048,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"158951567","profile_image_url":"http://a3.twimg.com/profile_images/962721419/Logo_3_normal.jpg","created_at":"Wed, 26 Jan 2011 01:58:31 +0000","from_user":"YubaVetTech","id_str":"30082124207886336","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Dr. Haskell has just been awarded the prestigious Hayward Award for \u2018Excellence in Education\u2019. This award honors... http://fb.me/QgQCxd74","id":30082124207886336,"from_user_id":158951567,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.facebook.com/twitter" rel="nofollow">Facebook</a>"},{"from_user_id_str":"158951567","profile_image_url":"http://a3.twimg.com/profile_images/962721419/Logo_3_normal.jpg","created_at":"Wed, 26 Jan 2011 01:56:04 +0000","from_user":"YubaVetTech","id_str":"30081505476743168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Dr. Haskell has just been awarded the prestigous Haward Award for Excellence in Education. This award honors... http://fb.me/PC9mYmCR","id":30081505476743168,"from_user_id":158951567,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.facebook.com/twitter" rel="nofollow">Facebook</a>"},{"from_user_id_str":"2331498","profile_image_url":"http://a3.twimg.com/profile_images/494632120/me_normal.jpg","created_at":"Wed, 26 Jan 2011 01:43:50 +0000","from_user":"Verus","id_str":"30078427155406848","metadata":{"result_type":"recent"},"to_user_id":79273052,"text":"@kami_joe \u3044\u3084\uff0c\u8ab2\u984c\u306f\u89e3\u6c7a\u5bfe\u8c61(\u30d1\u30ba\u30eb\u3068\u304b)\u3092\u4e0e\u3048\u3089\u308c\u3066\uff0c\u554f\u984c\u5b9a\u7fa9\u3068\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0(\u6307\u5b9a\u8a00\u8a9e\u306fC++\u3082\u3057\u304f\u306fJava)\u3068\u3044\u3046\u3044\u308f\u3070\u666e\u901a\u306a\u8ab2\u984c\u3067\u306f\u3042\u308b\u3093\u3060\u3051\u3069\uff0e\u95a2\u6570\u578b\u8a00\u8a9e\u306fHaskell\u306e\u6388\u696d\u304c\u307e\u305f\u5225\u306b\u3042\u308b\u306e\uff0e","id":30078427155406848,"from_user_id":2331498,"to_user":"kami_joe","geo":null,"iso_language_code":"ja","to_user_id_str":"79273052","source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"79151233","profile_image_url":"http://a2.twimg.com/a/1295051201/images/default_profile_2_normal.png","created_at":"Wed, 26 Jan 2011 01:40:37 +0000","from_user":"cz_newdrafts","id_str":"30077617361125376","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell programming language http://bit.ly/gpPAwB","id":30077617361125376,"from_user_id":79151233,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://tommorris.org/" rel="nofollow">tommorris' hacksample</a>"},{"from_user_id_str":"2331498","profile_image_url":"http://a3.twimg.com/profile_images/494632120/me_normal.jpg","created_at":"Wed, 26 Jan 2011 01:02:57 +0000","from_user":"Verus","id_str":"30068139416879104","metadata":{"result_type":"recent"},"to_user_id":9252720,"text":"@shukukei Java\u3068C\u306f\u3042\u308b\u7a0b\u5ea6\u66f8\u3051\u3066\u3042\u305f\u308a\u307e\u3048\u306a\u3068\u3053\u308d\u304c\u3042\u308b\u304b\u3089\u306a\u30fc\uff0ePython\u306f\u500b\u4eba\u7684\u306b\u611f\u899a\u304c\u5408\u308f\u306a\u3044\uff0e\u611f\u899a\u306a\u306e\u3067\uff0c\u3082\u3046\u3069\u3046\u3057\u3088\u3046\u3082\u306a\u3044\uff57 \u3044\u307e\u306fScala\u3068Haskell\u3092\u3082\u3063\u3068\u6975\u3081\u305f\u3044\u3068\u3053\u308d\uff0e","id":30068139416879104,"from_user_id":2331498,"to_user":"shukukei","geo":null,"iso_language_code":"ja","to_user_id_str":"9252720","source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"2781460","profile_image_url":"http://a0.twimg.com/profile_images/82526625/.joeyicon_normal.jpg","created_at":"Wed, 26 Jan 2011 01:02:35 +0000","from_user":"joeyhess","id_str":"30068046538219520","metadata":{"result_type":"recent"},"to_user_id":null,"text":"just figured out that I can use parameterized types to remove a dependency loop in git-annex's type definitions. whee #haskell","id":30068046538219520,"from_user_id":2781460,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://identi.ca" rel="nofollow">identica</a>"},{"from_user_id_str":"144546280","profile_image_url":"http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png","created_at":"Wed, 26 Jan 2011 00:54:22 +0000","from_user":"listwarenet","id_str":"30065977920061440","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://www.listware.net/201101/haskell-beginners/84466-haskell-beginners-bytestring-question.html Haskell-beginners - Bytestrin","id":30065977920061440,"from_user_id":144546280,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>"},{"from_user_id_str":"1291845","profile_image_url":"http://a0.twimg.com/profile_images/1225743404/ThinOxygen-small-opaque-solidarity_normal.png","created_at":"Wed, 26 Jan 2011 00:52:07 +0000","from_user":"_aaron_","id_str":"30065412242669568","metadata":{"result_type":"recent"},"to_user_id":null,"text":"wanted: librly licensed high level native compiled lang with min runtime (otherwise cobra/mono would be perfect) for win. lua? haskell? ooc?","id":30065412242669568,"from_user_id":1291845,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"5912444","profile_image_url":"http://a2.twimg.com/profile_images/546261026/ssf0xg11_normal.jpg","created_at":"Wed, 26 Jan 2011 00:45:45 +0000","from_user":"shelarcy","id_str":"30063810773516288","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @Hackage: download 0.3.1.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/eHfiJB","id":30063810773516288,"from_user_id":5912444,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"135993","profile_image_url":"http://a2.twimg.com/profile_images/1190667086/myface2010small_normal.jpg","created_at":"Wed, 26 Jan 2011 00:41:00 +0000","from_user":"kudzu_naoki","id_str":"30062613287141376","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @tanakh: \u9b54\u6cd5Haskell\u5c11\u5973\u5019\u88dc\u3092\u63a2\u3059\u306e\u3082\u5927\u5909\u306a\u3093\u3060","id":30062613287141376,"from_user_id":135993,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"52620546","profile_image_url":"http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png","created_at":"Wed, 26 Jan 2011 00:40:25 +0000","from_user":"omasanori","id_str":"30062465656033280","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u9b54\u6cd5Haskell\u5c11\u5973\u306e\u4e00\u65e5\u306fGHC HEAD\u306e\u30d3\u30eb\u30c9\u304b\u3089\u59cb\u307e\u308b","id":30062465656033280,"from_user_id":52620546,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>"},{"from_user_id_str":"52620546","profile_image_url":"http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png","created_at":"Wed, 26 Jan 2011 00:37:12 +0000","from_user":"omasanori","id_str":"30061656331526144","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01","id":30061656331526144,"from_user_id":52620546,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"135993","profile_image_url":"http://a2.twimg.com/profile_images/1190667086/myface2010small_normal.jpg","created_at":"Wed, 26 Jan 2011 00:35:42 +0000","from_user":"kudzu_naoki","id_str":"30061282665168896","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01","id":30061282665168896,"from_user_id":135993,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"1631333","profile_image_url":"http://a1.twimg.com/profile_images/81268862/profile300_normal.jpg","created_at":"Wed, 26 Jan 2011 00:30:02 +0000","from_user":"qnighy","id_str":"30059855884582913","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01","id":30059855884582913,"from_user_id":1631333,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"9093754","profile_image_url":"http://a1.twimg.com/profile_images/99435906/PHD_3d_col_blk_normal.jpg","created_at":"Wed, 26 Jan 2011 00:26:20 +0000","from_user":"phdwine","id_str":"30058925516656640","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Last weekend of Tri Nations Tasting with PHD wines at Haskell Vineyards. Hope you didn't miss the Pinot Noir tasting last week !","id":30058925516656640,"from_user_id":9093754,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"2119923","profile_image_url":"http://a2.twimg.com/profile_images/1096701078/djayprofile_normal.jpg","created_at":"Wed, 26 Jan 2011 00:21:14 +0000","from_user":"djay75","id_str":"30057639543050240","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @dnene: Skilled Calisthenics. Haskell code that outputs python which spits ruby which emits the haskell source. http://j.mp/YlQUL via @mfeathers","id":30057639543050240,"from_user_id":2119923,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"134323731","profile_image_url":"http://a2.twimg.com/profile_images/1225818824/IMG00518-20110125-1547_normal.jpg","created_at":"Wed, 26 Jan 2011 00:19:30 +0000","from_user":"PrinceOfBrkeley","id_str":"30057205554216960","metadata":{"result_type":"recent"},"to_user_id":167093027,"text":"@PayThaPrince go to haskell.","id":30057205554216960,"from_user_id":134323731,"to_user":"PayThaPrince","geo":null,"iso_language_code":"en","to_user_id_str":"167093027","source":"<a href="http://blackberry.com/twitter" rel="nofollow">Twitter for BlackBerry\u00ae</a>"},{"from_user_id_str":"705857","profile_image_url":"http://a1.twimg.com/profile_images/429483912/ben_twitter_normal.jpg","created_at":"Wed, 26 Jan 2011 00:03:28 +0000","from_user":"bennadel","id_str":"30053166972141569","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Using #Homebrew to install Haskell - the last of the Seven Languages (in Seven Weeks) http://bit.ly/eA9Cv1 This has been some journey.","id":30053166972141569,"from_user_id":705857,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"251466","profile_image_url":"http://a2.twimg.com/profile_images/1194100934/pass_normal.jpg","created_at":"Wed, 26 Jan 2011 00:02:54 +0000","from_user":"simonszu","id_str":"30053025502466048","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Ouh yeah! Ich werde doch produktiv sein, diese Semesterferien. Ich werde funktional Programmieren lernen. #haskell, Baby.","id":30053025502466048,"from_user_id":251466,"geo":null,"iso_language_code":"de","to_user_id_str":null,"source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"357786","profile_image_url":"http://a0.twimg.com/profile_images/612044841/FM_2010_normal.jpg","created_at":"Tue, 25 Jan 2011 23:59:13 +0000","from_user":"diligiant","id_str":"30052100973006848","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @paulrbrown: "...we only discovered a single bug after compilation." (http://t.co/K0wlEYz) #haskell","id":30052100973006848,"from_user_id":357786,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"101597523","profile_image_url":"http://a1.twimg.com/profile_images/1206183256/2010-12-12-204902_normal.jpg","created_at":"Tue, 25 Jan 2011 23:54:46 +0000","from_user":"wlad_kent","id_str":"30050977964892160","metadata":{"result_type":"recent"},"to_user_id":86297184,"text":"@Nilson_Neto Isso eh bem basico. quando vc estiver estudando recurs\u00e3o em Haskell, ai vc vai ver oq eh papo de nerd - kkk - 1\u00ba periodo isso.","id":30050977964892160,"from_user_id":101597523,"to_user":"Nilson_Neto","geo":null,"iso_language_code":"pt","to_user_id_str":"86297184","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"144546280","profile_image_url":"http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png","created_at":"Tue, 25 Jan 2011 23:51:22 +0000","from_user":"listwarenet","id_str":"30050123383832577","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://www.listware.net/201101/haskell-cafe/84336-haskell-cafe-monomorphic-let-bindings-and-darcs.html Haskell-cafe - Monomorph","id":30050123383832577,"from_user_id":144546280,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>"},{"from_user_id_str":"5776901","profile_image_url":"http://a0.twimg.com/profile_images/472682157/lucabw_normal.JPG","created_at":"Tue, 25 Jan 2011 23:48:40 +0000","from_user":"lsbardel","id_str":"30049446469312512","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Very interesting technology stack these guys use http://bit.ly/ghAjS7 #python #redis #haskell","id":30049446469312512,"from_user_id":5776901,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"3005901","profile_image_url":"http://a0.twimg.com/profile_images/278943006/Lone_Pine_Peak_-_Peter_200x200_normal.jpg","created_at":"Tue, 25 Jan 2011 23:45:48 +0000","from_user":"pmonks","id_str":"30048721110573056","metadata":{"result_type":"recent"},"to_user_id":203834278,"text":"@techielicous Haskell: http://bit.ly/gy3oFi ;-)","id":30048721110573056,"from_user_id":3005901,"to_user":"techielicous","geo":null,"iso_language_code":"en","to_user_id_str":"203834278","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"162697074","profile_image_url":"http://a2.twimg.com/profile_images/826205838/ryan3_normal.jpg","created_at":"Tue, 25 Jan 2011 23:44:47 +0000","from_user":"TheRonaldMCD","id_str":"30048468781244416","metadata":{"result_type":"recent"},"to_user_id":null,"text":"I'm at Aldi Food Market (4122 Gaston Ave, Haskell, Dallas) http://4sq.com/ekqRY7","id":30048468781244416,"from_user_id":162697074,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://foursquare.com" rel="nofollow">foursquare</a>"},{"from_user_id_str":"203834278","profile_image_url":"http://a0.twimg.com/profile_images/1223375080/me_normal.jpg","created_at":"Tue, 25 Jan 2011 23:44:04 +0000","from_user":"techielicous","id_str":"30048286589067264","metadata":{"result_type":"recent"},"to_user_id":3005901,"text":"@pmonks I was thinking Haskell or Scheme","id":30048286589067264,"from_user_id":203834278,"to_user":"pmonks","geo":null,"iso_language_code":"en","to_user_id_str":"3005901","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"537690","profile_image_url":"http://a3.twimg.com/profile_images/45665122/nushiostamp_normal.jpg","created_at":"Tue, 25 Jan 2011 23:38:14 +0000","from_user":"nushio","id_str":"30046818658164737","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u305d\u3046\u3044\u3084\u5951\u7d04\u306b\u3088\u308b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3068\u304b\u3042\u3063\u305f\u306a\u3002Haskell\u306a\u3093\u304b\u3088\u308a\u3042\u3063\u3061\u306e\u65b9\u304c\u9b54\u6cd5\u5c11\u5973\u547c\u3070\u308f\u308a\u306b\u3075\u3055\u308f\u3057\u3044\u3002","id":30046818658164737,"from_user_id":537690,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"181192","profile_image_url":"http://a2.twimg.com/profile_images/1089890701/q530888600_9828_normal.jpg","created_at":"Tue, 25 Jan 2011 23:38:03 +0000","from_user":"aodag","id_str":"30046772223016960","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @omasanori: \u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d","id":30046772223016960,"from_user_id":181192,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>"},{"from_user_id_str":"5886055","profile_image_url":"http://a3.twimg.com/profile_images/85531669/ichi_normal.jpg","created_at":"Tue, 25 Jan 2011 23:37:53 +0000","from_user":"kanaya","id_str":"30046729243983873","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u9e97\u3057\u3044\u3002\u201c@omasanori: \u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d\u201d","id":30046729243983873,"from_user_id":5886055,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://itunes.apple.com/app/twitter/id333903271?mt=8" rel="nofollow">Twitter for iPad</a>"},{"from_user_id_str":"52620546","profile_image_url":"http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png","created_at":"Tue, 25 Jan 2011 23:36:26 +0000","from_user":"omasanori","id_str":"30046367187476481","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d","id":30046367187476481,"from_user_id":52620546,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>"},{"from_user_id_str":"1659992","profile_image_url":"http://a1.twimg.com/profile_images/504488750/1_normal.jpg","created_at":"Tue, 25 Jan 2011 23:16:13 +0000","from_user":"finalfusion","id_str":"30041278544609280","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @necocen: Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044","id":30041278544609280,"from_user_id":1659992,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"272513","profile_image_url":"http://a2.twimg.com/profile_images/320244078/Mike_Painting2_normal.png","created_at":"Tue, 25 Jan 2011 23:05:09 +0000","from_user":"mikehadlow","id_str":"30038492373319680","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Just written the same simple program in C#, F# and Haskell: 18, 12 and 9 LoC respectively. And I'm much better at C# than F# or Haskell.","id":30038492373319680,"from_user_id":272513,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"89393264","profile_image_url":"http://a0.twimg.com/profile_images/1169486472/020_portland_me_normal.jpg","created_at":"Tue, 25 Jan 2011 23:01:28 +0000","from_user":"newsportlandme","id_str":"30037564589084673","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Governor's Choice to Run Maine DOC Under Scrutiny - MPBN: State Rep. Anne Haskell, a Portland Democrat, says Mai... http://bit.ly/fO30gC","id":30037564589084673,"from_user_id":89393264,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"38138","profile_image_url":"http://a3.twimg.com/profile_images/1212565885/Screen_shot_2011-01-11_at_5.28.47_PM_normal.png","created_at":"Tue, 25 Jan 2011 22:59:55 +0000","from_user":"michaelneale","id_str":"30037174615281664","metadata":{"result_type":"recent"},"to_user_id":null,"text":"The haskell EvilMangler http://t.co/P2Tls7J","id":30037174615281664,"from_user_id":38138,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"45692","profile_image_url":"http://a3.twimg.com/profile_images/1177741507/dogkarno_r_normal.jpg","created_at":"Tue, 25 Jan 2011 22:45:06 +0000","from_user":"karno","id_str":"30033448286552064","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell\u3063\u3066\u95a2\u6570\u306b\u30ab\u30ec\u30fc\u7c89\u3076\u3061\u8fbc\u3080\u3068\u304b\u306a\u3093\u3068\u304b","id":30033448286552064,"from_user_id":45692,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://yubitter.com/" rel="nofollow">yubitter</a>"},{"from_user_id_str":"27605","profile_image_url":"http://a2.twimg.com/profile_images/15826632/meron_normal.jpg","created_at":"Tue, 25 Jan 2011 22:44:23 +0000","from_user":"celeron1ghz","id_str":"30033268761956352","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @necocen: Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044","id":30033268761956352,"from_user_id":27605,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"12901","profile_image_url":"http://a1.twimg.com/profile_images/56091349/haruhi_nagato-Y_normal.jpg","created_at":"Tue, 25 Jan 2011 22:43:30 +0000","from_user":"necocen","id_str":"30033044035346432","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u307e\u3042Haskell\u77e5\u3089\u3093\u3057\u306d","id":30033044035346432,"from_user_id":12901,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"12901","profile_image_url":"http://a1.twimg.com/profile_images/56091349/haruhi_nagato-Y_normal.jpg","created_at":"Tue, 25 Jan 2011 22:42:54 +0000","from_user":"necocen","id_str":"30032894856531968","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044","id":30032894856531968,"from_user_id":12901,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"10821270","profile_image_url":"http://a0.twimg.com/profile_images/1195474259/Salto_Marlon_normal.jpg","created_at":"Tue, 25 Jan 2011 22:35:09 +0000","from_user":"jjedMoriAnktah","id_str":"30030942106025984","metadata":{"result_type":"recent"},"to_user_id":null,"text":""A Haskell program that outputs a Python program that outputs a Ruby program that outputs the original Haskell program" http://is.gd/E6Julu","id":30030942106025984,"from_user_id":10821270,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"7554762","profile_image_url":"http://a0.twimg.com/profile_images/100515212/ajay-photo_normal.jpg","created_at":"Tue, 25 Jan 2011 22:34:30 +0000","from_user":"comatose_kid","id_str":"30030780205899776","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @bumptech: Bump Dev Blog - Why we use Haskell at Bump http://devblog.bu.mp/haskell-at-bump","id":30030780205899776,"from_user_id":7554762,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"148474705","profile_image_url":"http://a0.twimg.com/profile_images/1119234716/fur_hat_-_gilbeys_vodka_-_life_-_11-30-1962_normal.JPG","created_at":"Tue, 25 Jan 2011 22:29:19 +0000","from_user":"landmvintage","id_str":"30029476003840000","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @faerymoongodess: Magnificent Miriam Haskell Baroque Pearl Necklace by @MercyMadge http://etsy.me/hqRl51","id":30029476003840000,"from_user_id":148474705,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"37715508","profile_image_url":"http://a1.twimg.com/profile_images/1207891411/ballerina_normal.jpg","created_at":"Tue, 25 Jan 2011 22:24:52 +0000","from_user":"faerymoongodess","id_str":"30028356326002688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Magnificent Miriam Haskell Baroque Pearl Necklace by @MercyMadge http://etsy.me/hqRl51","id":30028356326002688,"from_user_id":37715508,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"17671137","profile_image_url":"http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png","created_at":"Tue, 25 Jan 2011 22:17:16 +0000","from_user":"Hackage","id_str":"30026442456694784","metadata":{"result_type":"recent"},"to_user_id":null,"text":"base16-bytestring 0.1.0.0, added by BryanOSullivan: Fast base16 (hex) encoding and deconding for ByteStrings http://bit.ly/eu75TN","id":30026442456694784,"from_user_id":17671137,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"199750997","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Tue, 25 Jan 2011 22:12:07 +0000","from_user":"benreads","id_str":"30025146991382528","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Writing Systems Software in a Functional Language -- brief, but fun. I want to see how well they can make Systems Haskell perform at scale.","id":30025146991382528,"from_user_id":199750997,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"35359797","profile_image_url":"http://a1.twimg.com/profile_images/1173453785/48893_521140819_1896062_q_normal.jpg","created_at":"Tue, 25 Jan 2011 22:09:45 +0000","from_user":"jcawthorne1","id_str":"30024549265309696","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Just saw Jeff Haskell give the middle finger!! Lol awesome","id":30024549265309696,"from_user_id":35359797,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"13540930","profile_image_url":"http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg","created_at":"Tue, 25 Jan 2011 22:06:44 +0000","from_user":"goodfox","id_str":"30023790381498369","metadata":{"result_type":"recent"},"to_user_id":null,"text":"At the Haskell Convocation. (@ Haskell Indian Nations U Auditorium) http://4sq.com/eKKXyn","id":30023790381498369,"from_user_id":13540930,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://foursquare.com" rel="nofollow">foursquare</a>"},{"from_user_id_str":"14674418","profile_image_url":"http://a2.twimg.com/profile_images/238230125/IMG_1030-1_normal.jpg","created_at":"Tue, 25 Jan 2011 22:02:31 +0000","from_user":"sanityinc","id_str":"30022731919523840","metadata":{"result_type":"recent"},"to_user_id":371289,"text":"@xshay Haskell's great, but Clojure's similarly lazy in all the ways that matter, and is more practical for day-to-day use.","id":30022731919523840,"from_user_id":14674418,"to_user":"xshay","geo":null,"iso_language_code":"en","to_user_id_str":"371289","source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"371289","profile_image_url":"http://a2.twimg.com/profile_images/1113482439/me-brisbane_normal.jpg","created_at":"Tue, 25 Jan 2011 21:58:29 +0000","from_user":"xshay","id_str":"30021714444292096","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Just made a lazy sequence of prime numbers in haskell. I'm smitten.","id":30021714444292096,"from_user_id":371289,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>"},{"from_user_id_str":"199453873","profile_image_url":"http://a3.twimg.com/a/1294785484/images/default_profile_3_normal.png","created_at":"Tue, 25 Jan 2011 21:48:40 +0000","from_user":"stackfeed","id_str":"30019243982454784","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Practical Scala reference manual, for searching things like method names: Hello, \n\nInspired by\nHaskell API Searc... http://bit.ly/g4zWZQ","id":30019243982454784,"from_user_id":199453873,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"17489366","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Tue, 25 Jan 2011 21:45:32 +0000","from_user":"aapnoot","id_str":"30018455189065728","metadata":{"result_type":"recent"},"to_user_id":null,"text":"download 0.3.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/i8mYvi","id":30018455189065728,"from_user_id":17489366,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"17489366","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Tue, 25 Jan 2011 21:45:31 +0000","from_user":"aapnoot","id_str":"30018452601180160","metadata":{"result_type":"recent"},"to_user_id":null,"text":"download 0.3.1.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/eHfiJB","id":30018452601180160,"from_user_id":17489366,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"17671137","profile_image_url":"http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png","created_at":"Tue, 25 Jan 2011 21:45:31 +0000","from_user":"Hackage","id_str":"30018451867176960","metadata":{"result_type":"recent"},"to_user_id":null,"text":"download 0.3.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/i8mYvi","id":30018451867176960,"from_user_id":17671137,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"138502705","profile_image_url":"http://a1.twimg.com/profile_images/1083845614/yclogo_normal.gif","created_at":"Tue, 25 Jan 2011 21:45:04 +0000","from_user":"newsyc100","id_str":"30018340839755777","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Haskell improves log processing 4x over Python http://devblog.bu.mp/haskell-at-bump (http://bit.ly/gQxxR8)","id":30018340839755777,"from_user_id":138502705,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://news.ycombinator.com" rel="nofollow">newsyc</a>"},{"from_user_id_str":"1578246","profile_image_url":"http://a0.twimg.com/profile_images/59312315/avatar_simpson_small_normal.jpg","created_at":"Tue, 25 Jan 2011 21:43:32 +0000","from_user":"magthe","id_str":"30017953801969665","metadata":{"result_type":"recent"},"to_user_id":null,"text":"New version of download uploaded to #hackage #haskell","id":30017953801969665,"from_user_id":1578246,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://api.supertweet.net" rel="nofollow">MyAuth API Proxy</a>"},{"from_user_id_str":"135838970","profile_image_url":"http://a2.twimg.com/profile_images/1079929891/logo_normal.png","created_at":"Tue, 25 Jan 2011 21:37:51 +0000","from_user":"reward999","id_str":"30016525180084224","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Found Great Dane (Main & Haskell- Dallas): We found a great dane. 214-712-0000 http://bit.ly/fQ8iBw","id":30016525180084224,"from_user_id":135838970,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"137719265","profile_image_url":"http://a2.twimg.com/profile_images/1092224079/8__4__normal.jpg","created_at":"Tue, 25 Jan 2011 21:34:22 +0000","from_user":"WeiMatas","id_str":"30015646020411392","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Fourth day Rez party Eddie Haskell County in second life \u2013 which took place in cabaret Tadd","id":30015646020411392,"from_user_id":137719265,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"<a href="http://dlvr.it" rel="nofollow">dlvr.it</a>"},{"from_user_id_str":"144546280","profile_image_url":"http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png","created_at":"Tue, 25 Jan 2011 21:33:21 +0000","from_user":"listwarenet","id_str":"30015392571195392","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://www.listware.net/201101/haskell-cafe/83889-haskell-cafe-gpl-license-of-h-matrix-and-prelude-numeric.html Haskell-cafe -","id":30015392571195392,"from_user_id":144546280,"geo":null,"iso_language_code":"no","to_user_id_str":null,"source":"<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>"}],"max_id":30121530767708160,"since_id":0,"refresh_url":"?since_id=30121530767708160&q=haskell","next_page":"?page=2&max_id=30121530767708160&rpp=100&q=haskell","results_per_page":100,"page":1,"completed_in":1.195569,"since_id_str":"0","max_id_str":"30121530767708160","query":"haskell"}
+ test/json-data/goldens/twitter_with_hex_vals.json.golden view
@@ -0,0 +1,1 @@+{"results":[{"from_user_id_str":"178045354","profile_image_url":"http://a0.twimg.com/profile_images/1214479381/154722_10100141954893059_808622_55276626_7445050_n_normal.jpg","created_at":"Fri, 25 Feb 2011 17:40:04 +0000","from_user":"ChuriSta_gt","id_str":"41190705623732224","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3072\u3089\u304c\u306a\u306e\u300c\u3064\u300d\u306f\u3082\u3046Twitter\u306e\u300c\u3064\u300d\u3060\uff01","id":41190705623732224,"from_user_id":178045354,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"71746558","profile_image_url":"http://a2.twimg.com/profile_images/591641547/wwd_normal.gif","created_at":"Fri, 25 Feb 2011 17:40:02 +0000","from_user":"fuckkilldiestar","id_str":"41190699571494912","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u306b\u3057\u3066\u3082Twitter\u3084pixiv\u96e2\u308c\u3092\u3069\u3046\u306b\u304b\u3057\u308d\u674f\u4ec1\u30d6\u30eb\u30de","id":41190699571494912,"from_user_id":71746558,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"131230176","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:39:58 +0000","from_user":"proory_bot","id_str":"41190683922546688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30ea\u30cd\u30f3\u30dd\u30fc\u30c1 http://bit.ly/btjqlH","id":41190683922546688,"from_user_id":131230176,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://proory.com/" rel="nofollow">proory tems</a>"},{"from_user_id_str":"120359038","profile_image_url":"http://a1.twimg.com/profile_images/946521484/200805161826000_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:58 +0000","from_user":"tukinosuke","id_str":"41190680835391488","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41190680835391488,"from_user_id":120359038,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"166512109","profile_image_url":"http://a3.twimg.com/profile_images/1224583217/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:50 +0000","from_user":"yurii1129","id_str":"41190649839620096","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4eca\u6c17\u4ed8\u3044\u305f\u2026\u307f\u3043\u304f\u3093\u306eTwitter\u540d\u3001\u3084\u307e\u306d\u3084\u3093(\uffe3\u25c7\uffe3;)","id":41190649839620096,"from_user_id":166512109,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"228999619","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","created_at":"Fri, 25 Feb 2011 17:39:49 +0000","from_user":"takami926","id_str":"41190644793745408","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7530\u539f\u3055\u3093\u3001\u5fdc\u63f4\u3057\u3066\u307e\u3059\u3002WEB\u3082TWITTER\u3082\u62dd\u898b\u3057\u3066\u307e\u3059\u3002\u7530\u539f\u3055\u3093\u304c\u653f\u6cbb\u5bb6\u306b\u306a\u3063\u3066\u3001\u65e5\u672c\u3092\u5909\u3048\u3066\u304f\u3060\u3055\u3044\u3002\u5c16\u95a3\u3001\u5317\u65b9\u554f\u984c\u5171\u306b\u65e5\u672c\u306e\u653f\u6cbb\u306e\u5931\u6557\u3067\u3059\u3002\u8a55\u8ad6\u5bb6\u306f\u8272\u3005\u8a00\u3063\u3066\u307e\u3059\u304c\u3001\u4e2d\u6771\u307b\u3069\u56fd\u6c11\u306e\u71b1\u6c17\u304c\u7121\u304f\u3001\u683c\u5dee\u304c\u3042\u308a\u3001\u4f55\u3082\u5909\u308f\u3089\u306a\u3044\u666f\u6c17\u4f4e\u8ff7\u306e\u65e5\u672c\u306b\u56fd\u6c11\u306f\u8ae6\u3081\u3066\u308b\u3093\u3067\u3059\u3002","id":41190644793745408,"from_user_id":228999619,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"151773701","profile_image_url":"http://a0.twimg.com/profile_images/1213699753/obi_nao_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:44 +0000","from_user":"obi_nao","id_str":"41190622949941248","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3060\u3044\u3076\u5e74\u4e0b\u306e\u5f8c\u8f29\u306b\u3001\u30d3\u30b8\u30cd\u30b9\u3084\u308b\u306a\u3089\u771f\u5263\u306bTwitter\u3084\u308c\uff01\u3063\u3066\u6012\u3089\u308c\u305f\u3002\u306a\u306e\u3067\u4eca\u65e5\u304b\u3089\u771f\u5263\u306b\u3064\u3076\u3084\u304f\u3053\u3068\u306b\u3057\u307e\u3059\u3002\u3088\u308d\u3057\u304f\u3067\u3059\u3002","id":41190622949941248,"from_user_id":151773701,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"20817229","profile_image_url":"http://a0.twimg.com/profile_images/1212012721/205_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:43 +0000","from_user":"allte","id_str":"41190619804082176","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7206\u7b11\u3057\u3066\u547c\u5438\u56f0\u96e3\u3067\u75d9\u6523\u3059\u308b\u5618\u304f\u3093\u304c\u898b\u308c\u308b\u306e\u306fTwitter\u3060\u3051","id":41190619804082176,"from_user_id":20817229,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>"},{"from_user_id_str":"166907967","profile_image_url":"http://a2.twimg.com/profile_images/1250526230/___normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:43 +0000","from_user":"NTTYAHOOOOOOOI","id_str":"41190618235412480","metadata":{"result_type":"recent"},"to_user_id":106469594,"text":"@takahirororo \u3066\u304b\u4f55\u3067twitter\u4e0a\u3067\u30a2\u30c9\u30d0\u30a4\u30b9\u3082\u3089\u3063\u3066\u3093\u306d\u3093\uff57","id":41190618235412480,"from_user_id":166907967,"to_user":"takahirororo","geo":null,"iso_language_code":"ja","to_user_id_str":"106469594","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"82581287","profile_image_url":"http://a0.twimg.com/profile_images/774721566/miyaru2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:38 +0000","from_user":"kine_rahchaos","id_str":"41190598132244480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30aa\u30b7\u30de\u3055\u3093\u304cTwitter\u59cb\u3081\u305f\u3060\u3068\u2026","id":41190598132244480,"from_user_id":82581287,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"136633905","profile_image_url":"http://a2.twimg.com/profile_images/1247161991/yama_normal.png","created_at":"Fri, 25 Feb 2011 17:39:35 +0000","from_user":"yamachi39","id_str":"41190584706285568","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3084\u3063\u3071\u308amixi\u3088\u308atwitter\u306e\u304c\u597d\u304d\u304b\u3082","id":41190584706285568,"from_user_id":136633905,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://jigtwi.jp/?p=1" rel="nofollow">jigtwi</a>"},{"from_user_id_str":"44029295","profile_image_url":"http://a2.twimg.com/profile_images/1112965522/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:32 +0000","from_user":"no2yosee","id_str":"41190572769280000","metadata":{"result_type":"recent"},"to_user_id":97721124,"text":"@hn0345 \u3042\u3001\u500b\u4eba\u7684\u306b\u306f\u4eca\u306ftwitter\u306e\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u306b\u66f8\u3044\u3066\u3042\u308b\u30d6\u30ed\u30b0\u306e\u30e6\u30cb\u30c3\u30c8\u3092\u306e\u3093\u3073\u308a\u3084\u3063\u3066\u307e\u3059w","id":41190572769280000,"from_user_id":44029295,"to_user":"hn0345","geo":null,"iso_language_code":"ja","to_user_id_str":"97721124","source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"149872179","profile_image_url":"http://a0.twimg.com/profile_images/1145770150/Winter11_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:31 +0000","from_user":"xmyyyxx","id_str":"41190566951653376","metadata":{"result_type":"recent"},"to_user_id":95069405,"text":"@rindofu \u653b\u7565\u672c\u3042\u308c\u3070\u3044\u3044\u306e\u306b\u3063\u3066\u601d\u3044\u307e\u3059(T\u03c9T)/~~~ \u79c1\u3082\u76f4\u3057\u305f\u3044\u3068\u3053\u3044\u3063\u3071\u3044\u3060\u3051\u3069\u3001\u3042\u306860\u5e74\u304f\u3089\u3044\u3044\u304d\u3089\u308c\u308b\u306f\u305a\u3060\u3057\u3001\u306e\u3093\u3073\u308a\u76f4\u308c\u3070\u3044\u3044\u306a\u3042 \u304a\u3084\u3059\u307f\u3067\u3059^^\uff01\u308a\u3093\u3055\u3093\u3068twitter\u3067\u4ef2\u826f\u304f\u306a\u308c\u3066\u3088\u304b\u3063\u305f\u3067\u3059\u3063","id":41190566951653376,"from_user_id":149872179,"to_user":"rindofu","geo":null,"iso_language_code":"ja","to_user_id_str":"95069405","source":"<a href="http://twtr.jp" rel="nofollow">Keitai Web</a>"},{"from_user_id_str":"105579892","profile_image_url":"http://a0.twimg.com/profile_images/1212950455/love_happy_pink_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:30 +0000","from_user":"love_happy_pink","id_str":"41190566494601216","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u305d\u308c\u898b\u305f\u3044\u306a\u266aRT @kazukt \u3046\u308b\u304a\u307c\u7d75\u3001\u4ed6\u306e\u4eba\u306e\u3082\u898b\u3066\u3044\u305f\u3089\u3084\u305f\u3089\u30de\u30f3\u30ac\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u3067\u3080\u3061\u3083\u304f\u3061\u3083\u4e0a\u624b\u3044\u4eba\u304c\uff01\u2026\u3068\u3001\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u898b\u305f\u3089\u3001\u306a\u3093\u3068\u3054\u672c\u4eba\u304c\u66f8\u3044\u3066\u3044\u3089\u3063\u3057\u3083\u3063\u305f\u3002Twitter\u3063\u3066\u30b9\u30b4\u30a4\u308f\u3002","id":41190566494601216,"from_user_id":105579892,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.nibirutech.com/" rel="nofollow">TwitBird iPad</a>"},{"from_user_id_str":"16996368","profile_image_url":"http://a0.twimg.com/profile_images/1198892387/pochi_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:30 +0000","from_user":"HyoYoshikawa","id_str":"41190564187611136","metadata":{"result_type":"recent"},"to_user_id":1800565,"text":"@shinichiro_beck \u73fe\u5730\u304b\u3089\u306a\u3089\u826f\u304f\u3066\u4ed6\u306e\u5730\u57df\u304b\u3089\u3060\u4f59\u8a08\u306a\u3089\u3001\u4f55\u306e\u305f\u3081\u306bTwitter\u304c\u3042\u308b\u306e\u304b\u308f\u304b\u3089\u306a\u3044\u3088\u3002\u3044\u307e\u8d77\u304d\u3066\u308b\u3053\u3068\u306e\u8aac\u660e\u3082\u3064\u304b\u306a\u3044\u3002\u30a2\u30eb\u30b8\u30e3\u30b8\u30fc\u30e9\u304c\u4f1d\u3048\u3066\u308b\u3053\u3068\u304c\u5168\u3066\u3058\u3083\u306a\u3044\u3057\u3001\u65e5\u672c\u306eTV\u306f\u4f1d\u3048\u306a\u3044\u3067\u3057\u3087\u3046\u3002\u77e5\u308a\u305f\u304c\u3063\u3066\u308b\u4eba\u3082\u305f\u304f\u3055\u3093\u3044\u308b\u3002","id":41190564187611136,"from_user_id":16996368,"to_user":"shinichiro_beck","geo":null,"iso_language_code":"ja","to_user_id_str":"1800565","source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"119070802","profile_image_url":"http://a2.twimg.com/profile_images/1229773005/346d8435099798113a1326e1ba4949ee_normal.jpeg","created_at":"Fri, 25 Feb 2011 17:39:25 +0000","from_user":"takotako726","id_str":"41190545439207424","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u9b54\u6cd5\u5c11\u5973\u307e\u3069\u304b\u30de\u30ae\u30ab\u306e\u53cd\u97ff\u304ctwitter\u3067\u306f\u3093\u3071\u306d\u3048\u4ef6\u3002","id":41190545439207424,"from_user_id":119070802,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"165695316","profile_image_url":"http://a1.twimg.com/profile_images/681748782/ring_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:21 +0000","from_user":"pandora_shotbar","id_str":"41190526447390720","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300e\u30b7\u30e7\u30c3\u30c8\u30d0\u30fc\u3000\u30d1\u30f3\u30c9\u30e9\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u300f\u30b7\u30e7\u30c3\u30c8\u30d0\u30fc\u3000\u30d1\u30f3\u30c9\u30e9\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u2026\uff5chttp://pandora-twitter.seesaa.net/article/187809936.html","id":41190526447390720,"from_user_id":165695316,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://blog.seesaa.jp/" rel="nofollow">SeesaaBlog</a>"},{"from_user_id_str":"88862311","profile_image_url":"http://a2.twimg.com/profile_images/1182243698/161113_100001897885617_169366_q_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:16 +0000","from_user":"amebaguide","id_str":"41190504926416896","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300e\u30a2\u30e1\u30d6\u30ed\u653b\u7565\u30ac\u30a4\u30c9\u306e\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u300f\u30d6\u30ed\u30b0\u306e\u653b\u7565\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u96c6\uff5chttp://accessup-twitter.seesaa.net/article/187809931.html","id":41190504926416896,"from_user_id":88862311,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://blog.seesaa.jp/" rel="nofollow">SeesaaBlog</a>"},{"from_user_id_str":"186895007","profile_image_url":"http://a2.twimg.com/profile_images/1229610799/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:11 +0000","from_user":"zizikt","id_str":"41190486123356161","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u308c\u306f\u500b\u4eba\u7684\u306b\u306f\u91cd\u5b9d\u3067\u3059\u3002\n\u25c6iPhone&iPad\u5411\u3051Twitter\u30a2\u30d7\u30ea\u300c\u3064\u3044\u3063\u3077\u308b\u300d\u306bEvernote\u3068\u306e\u9023\u643a\u6a5f\u80fd\u3092\u8ffd\u52a0 \nhttp://bit.ly/hPf44u","id":41190486123356161,"from_user_id":186895007,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"132320738","profile_image_url":"http://a3.twimg.com/profile_images/1229760475/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:04 +0000","from_user":"faina_","id_str":"41190453592334336","metadata":{"result_type":"recent"},"to_user_id":167894537,"text":"@gjmorley \u30e2\u30fc\u30ea\u30fc\u3055\u3093\u306e\u7ffb\u8a33\u306e\u8a00\u8449\u306e\u30bb\u30f3\u30b9\u304c\u3059\u304d\u3067\u3059\u3002\u305d\u3057\u3066\u3001Twitter\u3067\u77e5\u308b\u3001\u73fe\u5730\u306e\u4eba\u306e\u76ee\u306e\u529b\u3084\u3001\u60c5\u5831\u3092\u4f1d\u3048\u3066\u304f\u308c\u308b\u7686\u3055\u3093\u306e\u60c5\u71b1\u306b\u611f\u52d5\u3057\u3066\u3044\u307e\u3059\u3002\u611f\u52d5\u3059\u308b\u3063\u3066\u3059\u3054\u3044\u30a8\u30cd\u30eb\u30ae\u30fc\u3067\u3059\uff01\uff01","id":41190453592334336,"from_user_id":132320738,"to_user":"gjmorley","geo":null,"iso_language_code":"ja","to_user_id_str":"167894537","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"24870552","profile_image_url":"http://a3.twimg.com/profile_images/907130634/4_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:03 +0000","from_user":"tana1192","id_str":"41190450480021504","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u500b\u4eba\u7684\u306b\u306f\u3001\u30bf\u30b0\u5f3e\u304d\u3059\u308c\u3070\u3044\u3044\uff08\u5f3e\u3051\u308b\u30c4\u30fc\u30eb\u3092\u4f7f\u3063\u3066Twitter\u3092\u3059\u308c\u3070\u3044\u3044\uff09\u3068\u601d\u3046\u3093\u3060\u3051\u3069\u306a\u3042\u3002\u307f\u3093\u306a\u305d\u308c\u306a\u308a\u306bTwitter\u3084\u308b\u4eba\u3060\u3057\u3001\u30c4\u30fc\u30eb\u9078\u3073\u304f\u3089\u3044\u5e45\u3092\u6301\u3063\u3066\u3084\u3063\u3066\u3082\u3002 \u307e\u3042\u3001\u4ffa\u30a2\u30cb\u30e1\u306f\u89b3\u308b\u89b3\u308b\u8a50\u6b3a\u3059\u308b\u3060\u3051\u306e\u4eba\u3060\u304b\u3089\u95a2\u4fc2\u306a\u3044\u3093\u3060\u3051\u3069\u3082\uff57\uff57\u5b9f\u6cc1\u306f\u697d\u3057\u305d\u3046\u306b\u898b\u3048\u308b\u3088\u3002","id":41190450480021504,"from_user_id":24870552,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"58509646","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Fri, 25 Feb 2011 17:39:02 +0000","from_user":"kakuyas","id_str":"41190446663344128","metadata":{"result_type":"recent"},"to_user_id":107076877,"text":"@Dayspool \u6df1\u591c\uff12\uff19\u6642\u304f\u3089\u3044\u307e\u3067\u306f\u6bce\u65e5\u55b6\u696d\u3057\u3066\u308b\u306e\u3067\u3001twitter\u3001\u30e1\u30c3\u30bb\u3001PS3\u306a\u3069\u3067\u3088\u3093\u3067\u3051\u308c\u3002\u3053\u3063\u3061\u304b\u3089\u58f0\u304b\u3051\u308b\u3053\u3068\u3082\u3042\u308b\u304b\u3082\u3060\u304c\uff57","id":41190446663344128,"from_user_id":58509646,"to_user":"Dayspool","geo":null,"iso_language_code":"ja","to_user_id_str":"107076877","source":"<a href="http://cheebow.info/chemt/archives/2007/04/twitterwindowst.html" rel="nofollow">Twit for Windows</a>"},{"from_user_id_str":"149128527","profile_image_url":"http://a2.twimg.com/profile_images/1254922702/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:00 +0000","from_user":"uni13yoki","id_str":"41190437087748096","metadata":{"result_type":"recent"},"to_user_id":119468594,"text":"@kuro_wr84 \u304a\u308c\u3068\u304a\u524d\u3067Twitter\u3067\u4f1a\u8a71\u3057\u305f\u3089\u3001\u5927\u5909\u306a\u3053\u3068\u306b\u306a\u308b\u306a","id":41190437087748096,"from_user_id":149128527,"to_user":"kuro_wr84","geo":null,"iso_language_code":"ja","to_user_id_str":"119468594","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"18670595","profile_image_url":"http://a2.twimg.com/profile_images/1250674062/ProfilePhoto_normal.png","created_at":"Fri, 25 Feb 2011 17:38:59 +0000","from_user":"nyuuuuun","id_str":"41190436450222080","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3078\u30fc\u3053\u3093\u306a\u306b\u3088\u304f\u4f3c\u308b\u3053\u3068\u3082\u3042\u308b\u3093\u3060\u30fc\nhttp://twitter.com/Re_44/status/35943233016168448\nhttp://twitter.com/3510_misaka/status/36122114821988352","id":41190436450222080,"from_user_id":18670595,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"96267603","profile_image_url":"http://a3.twimg.com/profile_images/1245253473/DSiLL3_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:59 +0000","from_user":"arivis","id_str":"41190433119940608","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://twitter.com/#!/arivis/status/40636755380142080 \u306a\u3093\u3064\u3046\u304b\u3053\u308c\u3067\u8d64\u3063\u3066\u306e\u3082\u3061\u3087\u3063\u3068\u3042\u308c\u3063\u3059\u306d\u3002\u305d\u3057\u3066\u4e88\u671f\u3057\u3066\u3044\u305f\u304b\u306e\u3088\u3046\u3060","id":41190433119940608,"from_user_id":96267603,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"148097776","profile_image_url":"http://a3.twimg.com/profile_images/1166904064/broken-heart_normal.png","created_at":"Fri, 25 Feb 2011 17:38:56 +0000","from_user":"ReajuBreaker_A","id_str":"41190422135058432","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u672c\u57a2\u30d5\u30a9\u30ed\u30fc\u3088\u308d\u3057\u304f\u3067\u3059\u2192 http://twitter.com/ReajuBreaker \uff08\uff20\u3060\u3068\u30ea\u30d7\u30e9\u30a4\u304c\u57cb\u307e\u308b\u305f\u3081\u3001URL\u306b\u3057\u3066\u3042\u308a\u307e\u3059\uff09","id":41190422135058432,"from_user_id":148097776,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.twitter.com/ReajuBreaker" rel="nofollow">\u73fe\u5145\u6bba\u3057\u306e\u7121\u4eba\u9023\u545f\uff1c\u30aa\u30fc\u30c8\u30c4\u30a4\u30fc\u30c8\uff1e</a>"},{"from_user_id_str":"59711654","profile_image_url":"http://a2.twimg.com/profile_images/416212928/flowers-06-1_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:56 +0000","from_user":"agamo45","id_str":"41190421522546688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @ebizo66: \u30ea\u30d3\u30a2\u30fb\u30c8\u30ea\u30dd\u30ea\u306eTw\uff1a\u6551\u6025\u8eca\u304c\u6765\u305f\u304c\u3001\u8ca0\u50b7\u8005\u3092\u8eca\u5185\u3067\u6bba\u5bb3\u3057\u3066\u3044\u305f\u3001\u3068\u3002\uff08\u6ec5\u8336\u82e6\u8336\u3060\uff01\uff09http://ow.ly/43pQ2 #libjp","id":41190421522546688,"from_user_id":59711654,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"145311373","profile_image_url":"http://a3.twimg.com/profile_images/1187802576/a_gam_02_normal.png","created_at":"Fri, 25 Feb 2011 17:38:55 +0000","from_user":"nogic1008","id_str":"41190418141937664","metadata":{"result_type":"recent"},"to_user_id":88117317,"text":"@runasoru \u307e\u3042\u5acc\u306a\u3089\u6df1\u591c\u5e2f\u306bTwitter\u898b\u306a\u304d\u3083\u3044\u3044\u3060\u3051\u3067\u3059\u304b\u3089\u306d\u30fc \u30103/19BDM\u30aa\u30d5http://twvt.us/bdoff_kansai\u3011","id":41190418141937664,"from_user_id":145311373,"to_user":"runasoru","geo":null,"iso_language_code":"ja","to_user_id_str":"88117317","source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"195851300","profile_image_url":"http://a2.twimg.com/profile_images/1124572815/be7b4c0a06cb60e8_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:49 +0000","from_user":"LoveLAscrewDoll","id_str":"41190391147540480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @jp_mjp: SCREW TV SHOW Vol.6\u306e\u653e\u9001\u304c\u7121\u4e8b\u306b\u7d42\u4e86\u3044\u305f\u3057\u307e\u3057\u305f\u3002\u3054\u89a7\u9802\u304d\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3057\u305f\uff01\u6b21\u56de\u653e\u9001\u306f3\u670818\u65e5(\u91d1)\u3067\u3059\u3002\u8996\u8074\u8005\u30d7\u30ec\u30bc\u30f3\u30c8\u306e\u8a73\u7d30\u306f\u5f8c\u65e5MJP\u3067\u304a\u77e5\u3089\u305b\u3044\u305f\u3057\u307e\u3059\u3002\u305d\u306e\u969b\u306b\u306f\u3001\u3053\u306eTwitter\u3067\u3082\u304a\u77e5\u3089\u305b\u3044\u305f\u3057\u307e\u3059\u306e\u3067\u3001\u304a\u697d\u3057\u307f\u306b\uff01#SCREWTV","id":41190391147540480,"from_user_id":195851300,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"178045354","profile_image_url":"http://a0.twimg.com/profile_images/1214479381/154722_10100141954893059_808622_55276626_7445050_n_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:48 +0000","from_user":"ChuriSta_gt","id_str":"41190389549510656","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u3053\u4e00\u9031\u9593Twitter\u304c\u3084\u305f\u3089\u697d\u3057\u3044\u306e\u3067\u3059\u3051\u3069\u30fc\u30fc\u30fc\uff01\u306b\u3072\u3072\u3063\u7b11","id":41190389549510656,"from_user_id":178045354,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"50592111","profile_image_url":"http://a0.twimg.com/profile_images/1252176582/lFjpi_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:48 +0000","from_user":"crowNeko","id_str":"41190387271864320","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a8\u30ed\u30b2\u30d7\u30ec\u30a4\u3057\u306a\u304c\u3089\u307e\u3069\u30de\u30aeTL\u3092\u898b\u306a\u3044\u3088\u3046\u306b\u534a\u76ee\u306b\u306a\u308a\u306a\u304c\u3089Twitter\u3057\u3066\u308b\u6df1\u591c2\u6642\u534a\u3002","id":41190387271864320,"from_user_id":50592111,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://stone.com/Twittelator" rel="nofollow">Twittelator</a>"},{"from_user_id_str":"7141467","profile_image_url":"http://a3.twimg.com/profile_images/1198540741/icon12912579345276_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:40 +0000","from_user":"hina_geshi","id_str":"41190355961380864","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7d50\u5c40\u30cd\u30bf\u30d0\u30ec\u3059\u3093\u306a\u3063\u3066\u8a00\u3046\u65b9\u304c\u30a2\u30ec\u3060\u3088\u306d\u3001\u3057\u306a\u3044\u308f\u3051\u7121\u3044\u3058\u3083\u306a\u3044\u8133\u5185\u5782\u308c\u6d41\u3057\u304cTwitter\u306a\u3093\u3060\u304b\u3089\u3055","id":41190355961380864,"from_user_id":7141467,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://projects.playwell.jp/go/Saezuri" rel="nofollow">Saezuri</a>"},{"from_user_id_str":"149608984","profile_image_url":"http://a0.twimg.com/profile_images/1205950885/090702_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:39 +0000","from_user":"Mr_Tsubaki","id_str":"41190349447774208","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u307e\u3069\u304b\u306fTwitter\u5408\u308f\u305b\u3066\uff11\u6642\u9593\u306f\u697d\u3057\u3044","id":41190349447774208,"from_user_id":149608984,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"122271550","profile_image_url":"http://a0.twimg.com/profile_images/961936499/neoneko_bot5jpg_____normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:39 +0000","from_user":"neoneko_bot5","id_str":"41190348726345728","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u30c6\u30b9\u30c8\uff1a23\u3011\u4eca\u65e5\u304b\u3089\u5ba3\u4f1d\u958b\u59cb\u2606\u306d\u304a\u306d\u3053\u306eTwitter \u3067 EasyBottex\u3000\u3067\u304d\u308b\u307e\u3067\uff01\u2192http://neoneko.blog31.fc2.com/","id":41190348726345728,"from_user_id":122271550,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www20.atpages.jp/neoneko/" rel="nofollow">neoneko_bot5</a>"},{"from_user_id_str":"127069188","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","created_at":"Fri, 25 Feb 2011 17:38:37 +0000","from_user":"MYCHEBOT","id_str":"41190340908163074","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30eb\u30d5\u3055\u3093\u304c\u914d\u4fe1\u3092\u7d42\u4e86\u3057\u307e\u3057\u305f\uff01/ http://777labo.com/mychecker/view/745.php / \u30c8\u30d4\u30c3\u30af:XSplit\u30c6\u30b9\u30c8\u3000twitter\u2192http://twitter.com/rukh01","id":41190340908163074,"from_user_id":127069188,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://777labo.com/mychecker/" rel="nofollow">MYCHEBOT</a>"},{"from_user_id_str":"107626142","profile_image_url":"http://a1.twimg.com/profile_images/1104968421/SuperMaika1_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:34 +0000","from_user":"MaikaPaPa","id_str":"41190328614666240","metadata":{"result_type":"recent"},"to_user_id":null,"text":"75\u5e74\u524d\u306e\u4eca\u65e52\u670826\u65e5\u672a\u660e\u3001\u82e5\u304d\u9752\u5e74\u5c06\u6821\u3089\u304c\u653f\u6cbb\u8150\u6557\u3068\u8fb2\u6751\u306e\u56f0\u7aae\u306b\u5bfe\u3057\u3066\u6c7a\u8d77\u3057\u307e\u3057\u305f\u3002\u3082\u3061\u308d\u3093\u5f53\u6642\u306fTwitter\u3082FB\u3082\u3001\u307e\u305f\u5f53\u7136\u306a\u304c\u3089Internet\u3082\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u4e00\u65b9\u3001\u30c1\u30e5\u30cb\u30b8\u30a2\u3001\u30a8\u30b8\u30d7\u30c8\u3001\u4e2d\u6771\u306b\u5e83\u304c\u308b\u53cd\u653f\u5e9c\u30c7\u30e2\u3068\u5f37\u6a29\u4f53\u5236\u306e\u5d29\u58ca\u3002\u73fe\u5728\u306e\u65e5\u672c\u3067\u306f\u8003\u3048\u3089\u308c\u306a\u3044\u3053\u3068\u3067\u3059\u3002","id":41190328614666240,"from_user_id":107626142,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"11111695","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:38:28 +0000","from_user":"kumatchipooh","id_str":"41190306145775617","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @inosenaoki: \u306a\u308b\u307b\u3069\u306d\u3002 RT @dansrmz @inosenaoki \u3053\u3061\u3089\u304c\u30bd\u30d5\u30c8\u30d0\u30f3\u30af\u526f\u793e\u9577\u306e\u677e\u672c\u5fb9\u4e09\u3055\u3093\u306e\u3001Twitter\u306b\u95a2\u3059\u308b\u8ad6\u8003\u3067\u3059\u3002 \u25b6 "Twitter\u306e2\u30c1\u30e3\u30f3\u30cd\u30eb\u5316\u306f\u9632\u6b62\u51fa\u6765\u308b\u304b" http://t.co/Mwzb8Zf","id":41190306145775617,"from_user_id":11111695,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"212161909","profile_image_url":"http://a1.twimg.com/profile_images/1252895790/natm01_normal.gif","created_at":"Fri, 25 Feb 2011 17:38:28 +0000","from_user":"n34hitman","id_str":"41190303830511616","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u30fb\u30d6\u30ed\u30b0\u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8\u81ea\u52d5\u6295.... http://goo.gl/a4RHB 4054","id":41190303830511616,"from_user_id":212161909,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twibow.net/" rel="nofollow">Twibow</a>"},{"from_user_id_str":"105945593","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:38:24 +0000","from_user":"nakano_bot","id_str":"41190285710983168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u306ebot\u306f\u4e0d\u52d5\u7523\u4f1a\u793e\u69d8\u5411\u3051\u306e\u4e0d\u52d5\u7523\u30dd\u30fc\u30bf\u30eb\u30b5\u30a4\u30c8\u3078\u306e\u4e00\u62ec\u8ee2\u9001\uff0bTwitter\u7121\u6599\u8ee2\u9001\u30b5\u30fc\u30d3\u30b9\u306b\u3088\u308a\u3064\u3076\u3084\u304d\u307e\u3059\u3002\u3054\u5229\u7528\u306b\u306a\u308a\u305f\u3044\u5834\u5408\u306f http://bit.ly/demey0 \u306b\u304a\u6c17\u8efd\u306b\u304a\u554f\u3044\u5408\u308f\u305b\u4e0b\u3055\u3044\u3002","id":41190285710983168,"from_user_id":105945593,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.teramax.jp/aboutus.html" rel="nofollow">tmxbot</a>"},{"from_user_id_str":"170904226","profile_image_url":"http://a2.twimg.com/profile_images/1249020397/1789kb_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:21 +0000","from_user":"1789kb","id_str":"41190274428305408","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3068\u308a\u3042\u3048\u305a\u4eca\u56de\u521d\u3081\u3066\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u3067\u898b\u3066\u308f\u304b\u3063\u305f\u306e\u306f\u3001QB\u306f\u5168\u8eab\u304c\u30a2\u30f3\u30d1\u30f3\u30bf\u30a4\u30d7\u3060\u3068\u3044\u3046\u3053\u3068\u3068\u3001\u307e\u3069\u30de\u30ae\u7d42\u4e86\u5f8c\u306eTwitter\u306e\u3056\u308f\u3064\u304d\u304c\u3059\u3054\u3044\u3068\u3044\u3046\u3053\u3068","id":41190274428305408,"from_user_id":170904226,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"166169644","profile_image_url":"http://a1.twimg.com/profile_images/1217017679/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:18 +0000","from_user":"Okkkkkkkkkkun","id_str":"41190262420017152","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3063\u3066Twitter\u3067\u3064\u3076\u3084\u304f\u81ea\u5206\u3082\u76f8\u5f53\u5c0f\u3055\u3044\u306a\u3002","id":41190262420017152,"from_user_id":166169644,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"196623456","profile_image_url":"http://a3.twimg.com/profile_images/1219076661/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:06 +0000","from_user":"NoMoneyClub","id_str":"41190213342601216","metadata":{"result_type":"recent"},"to_user_id":195462431,"text":"@yosal15 \nTwitter\u3084\u3063\u3066\u308b\u3089\u3057\u3044\u3002\u3051\u3069\u3001\u898b\u3064\u304b\u3089\u306a\u3044\u3002","id":41190213342601216,"from_user_id":196623456,"to_user":"yosal15","geo":null,"iso_language_code":"ja","to_user_id_str":"195462431","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"126984048","profile_image_url":"http://a3.twimg.com/profile_images/1254579571/zipyaru-20090829-23-0012_normal.png","created_at":"Fri, 25 Feb 2011 17:38:02 +0000","from_user":"minaduki_naduki","id_str":"41190196418584576","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u203b\u30e1\u30fc\u30eb\u3067\u5973\u306e\u5b50\u53e3\u8aac\u304f\u306e\u306b\u5fd9\u3057\u3044\u3093\u3060\u305d\u3046\u3067\u3059\u3000\u307e\u3058\u3058\u3054\u308d RT @yowano_k: \u5fd9\u3057\u304f\u3066\u3082Twitter\u306b\u9854\u3092\u51fa\u3057\u305f\u304f\u306a\u308b\u50d5\u30a7\u2026\u2026","id":41190196418584576,"from_user_id":126984048,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://seesmic.com/seesmic_desktop/sd2" rel="nofollow">Seesmic Desktop</a>"},{"from_user_id_str":"200568705","profile_image_url":"http://a3.twimg.com/profile_images/1242179765/101230_1355_01_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:01 +0000","from_user":"hammerstrap","id_str":"41190190428979200","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6628\u65e5\u91d1\u66dc\u65e5\u306f\u732e\u8840\u306b\u5f80\u304f\u3002\u4eca\u306e\u50d5\u306e\u4eba\u9593\u3068\u3057\u3066\u306e\u4fa1\u5024\u306f\u3001\u7cbe\u3005\u3053\u306e\u7a0b\u5ea6\u3002\u8179\u304c\u6e1b\u3063\u305f\u3002\u5374\u8aac\u3002twitter\u306e\u767e\u56db\u5341\u6587\u5b57\u306b\u82db\u3005\u3068\u3057\u3066\u3001\u4e00\u3064\u306e\u4eee\u8aac\u306b\u4fe1\u6191\u6027\u3092\u5f97\u308b\u3002\u6226\u6642\u4e0b\u306e\u7d19\u306e\u7d71\u5236\u3068\u3001\u4e2d\u5cf6\u6566\u306e\u6587\u7ae0\u306e\u95a2\u4fc2\u6027\u3002\u73fe\u5728\u30a6\u30a7\u30d6\u30ed\u30b0\u306b\u3001\u7e8f\u3081\u3066\u3044\u308b\u6700\u4e2d\u3002\u8fd1\u65e5\u516c\u958b\u4e88\u5b9a\u3002","id":41190190428979200,"from_user_id":200568705,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"164970427","profile_image_url":"http://a0.twimg.com/profile_images/1227176662/9192b021ef85ce9902c28955f86e604b_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:59 +0000","from_user":"syuigetsuIT","id_str":"41190184041197569","metadata":{"result_type":"recent"},"to_user_id":141926331,"text":"@iliad_tga \u30a4\u30ea\u30a2\u30b9\u3055\u3093\u304c\u305d\u306e\u8fba\u7406\u89e3\u306e\u3042\u308b\u3053\u3068\u306f\u5206\u304b\u3063\u3066\u307e\u3059\uff57\u3000\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u306ftwitter\u306e\u6c7a\u5b9a\u7684\u306a\u6b20\u70b9\u3060\u3068\u601d\u3044\u307e\u3059\u306d\u3047\u3002","id":41190184041197569,"from_user_id":164970427,"to_user":"iliad_tga","geo":null,"iso_language_code":"ja","to_user_id_str":"141926331","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"94526795","profile_image_url":"http://a0.twimg.com/profile_images/679411954/akb48_in_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:56 +0000","from_user":"akb48_in","id_str":"41190171248431104","metadata":{"result_type":"recent"},"to_user_id":null,"text":"AKB48\u67cf\u6728\u7531\u7d00 \u304a\u75b2\u308c\u69d8\u3002: \n\u3053\u3093\u3070\u3093\u306f(^O^)\uff0f\u266a\n\u3000\n\u3000\n\u3000\n\u4eca\u65e5\u306e\u516c\u6f14\u697d\u3057\u304b\u3063\u305f\u301c\n\u3000\n\u3000\n\u4e45\u3057\u3076\u308a\u3067\u7dca\u5f35\u3057\u305f\u3051\u3069\u3001\u306f\u3058\u3051\u307e\u304f\u3063\u305f\u305c\u3043\uff01\uff01\n\u3000\n\u3000\n\u3000\nMC\u306f\u565b\u307f\u307e\u304f\u308a\u306e\u30c6\u30f3\u30d1\u308a\u307e\u304f... http://bit.ly/ie8bEa akb48 twitter","id":41190171248431104,"from_user_id":94526795,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"222270374","profile_image_url":"http://a3.twimg.com/profile_images/1250946143/P1040062_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:53 +0000","from_user":"chrxpac","id_str":"41190158455943168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u5b9a\u671f\u3011Twitter\u306f\uff8a\uff9f\uff7f\uff7a\uff9d\u304b\u3089\u3057\u304b\u3067\u304d\u306a\u3044\u306e\u3067\uff98\uff8c\uff9f\u8fd4\u3057\u304c\u9045\u304f\u306a\u308a\u307e\u3059(\u00b4\u30fb\u03c9\u30fb\uff40)\u3054\u4e86\u627f\u4e0b\u3055\u3044!!","id":41190158455943168,"from_user_id":222270374,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"64009258","profile_image_url":"http://a2.twimg.com/profile_images/1154025023/Mixi___normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:52 +0000","from_user":"Tatsuyuko","id_str":"41190153447944192","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4f01\u696d\u304c\u5c31\u6d3b\u751f\u306bFacebook\u3092\u4f7f\u3063\u3066\u7533\u8acb\u305b\u3088\u3068\u3044\u3044\u3001\u4f01\u696d\u304cFacebook\u3092\u4f7f\u3048\u3068\u4f01\u696d\u304c\u8a00\u3063\u3066\u304d\u305f\u308a\u3059\u308c\u3070\u305d\u308c\u3069\u3053\u308d\u3058\u3083\u306a\u3044\u304b\u3068\u3002\u5c11\u306a\u304f\u3068\u3082\u5c31\u6d3b\u3067Twitter\u306e\u8a00\u52d5\u3084\u30d5\u30a9\u30ed\u30ef\u30fc\u3092\u8abf\u67fb\u3059\u308b\u4f01\u696d\u306f\u304b\u306a\u308a\u591a\u3044\u3067\u3059 RT @Isshee: \u4f01\u696d\u3067\u3082\u540c\u3058\u3067\u3057\u3087 RT","id":41190153447944192,"from_user_id":64009258,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"105145175","profile_image_url":"http://static.twitter.com/images/default_profile_normal.png","created_at":"Fri, 25 Feb 2011 17:37:49 +0000","from_user":"snao813","id_str":"41190141703753728","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @yumisaiki: \u795e\u69d8\u306f\u672c\u5f53\u306b\u4eba\u9593\u3092\u3059\u3070\u3089\u3057\u3044\u30d0\u30e9\u30f3\u30b9\u3067\u914d\u7f6e\u3057\u3066\u304a\u3089\u308c\u308b\u3002\u795d\u5cf6\u307f\u305f\u3044\u306a\u5c0f\u3055\u3044\u3068\u3053\u308d\u306b\u306a\u3093\u3067\u3053\u3093\u306a\u306b\u7acb\u6d3e\u306a\u4eba\u304c\u305f\u304f\u3055\u3093\u3044\u308b\u3093\u3060\u308d\u3046\u3002\u795e\u69d8\u3042\u308a\u304c\u3068\u3046\u3002\u672c\u5f53\u306b\u3042\u308a\u304c\u3068\u3046\u3002\u4eba\u9593\u3063\u3066\u3059\u3070\u3089\u3057\u3044\u3068\u601d\u3048\u305f\u3002twitter\u3082\u3042\u308a\u304c\u3068\u3046\u3002\u3000#kaminoseki","id":41190141703753728,"from_user_id":105145175,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://seesmic.com/seesmic_desktop/sd2" rel="nofollow">Seesmic Desktop</a>"},{"from_user_id_str":"203667204","profile_image_url":"http://a2.twimg.com/profile_images/1254664000/eve_blackcat_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:46 +0000","from_user":"eve_blackcat","id_str":"41190129292943361","metadata":{"result_type":"recent"},"to_user_id":146894340,"text":"@kuroiso02 \u3057\u308a\u3068\u308a\u3068\u304b\uff1f\n\u2026\u3067\u3082Twitter\u3060\u3068\u7d42\u308f\u3089\u306a\u304f\u306a\u308b\u30b1\u30c9\u2026","id":41190129292943361,"from_user_id":203667204,"to_user":"kuroiso02","geo":null,"iso_language_code":"ja","to_user_id_str":"146894340","source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"6528403","profile_image_url":"http://a0.twimg.com/profile_images/1240591244/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:45 +0000","from_user":"sortiee","id_str":"41190125924917248","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30cb\u30e1\u5b9f\u6cc1\u306ftwitter\u306e\u764c","id":41190125924917248,"from_user_id":6528403,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sites.google.com/site/peraperaprv/Home" rel="nofollow">P3:PeraPeraPrv</a>"},{"from_user_id_str":"186058304","profile_image_url":"http://a0.twimg.com/profile_images/1250454564/IMG_0210_normal.JPG","created_at":"Fri, 25 Feb 2011 17:37:37 +0000","from_user":"00o8o00","id_str":"41190090386448384","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41190090386448384,"from_user_id":186058304,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"49219631","profile_image_url":"http://a2.twimg.com/profile_images/1231873117/__2-colornow__2__normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:33 +0000","from_user":"irisgazer","id_str":"41190073227550720","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3067\u3059\u3088\u306d\u3047 RT @minamitaiheiyou: \u6545\u306b\u30cd\u30bf\u30d0\u30ec\u3092\u3059\u308b\u306e\u3082\u81ea\u7531\u3002\u30cd\u30bf\u3070\u308c\u3057\u305f\u4eba\u3092\u30c7\u30a3\u30b9\u308b\u306e\u3082\u81ea\u7531\u3002\u3042\u3068\u306f\u5404\u3005\u306e\u88c1\u91cf\u3067\u4e57\u308a\u5207\u3063\u3066\u304f\u3060\u3055\u3044\u3088\u3081\u3093\u3069\u304f\u3055\u3044\u306a RT @kihirokiro: Twitter\u3067\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u3044\u3063\u3066\u3082\u5143\u3005Twitter\u3063\u3066\u300c\u500b\u4eba\u306e\u72ec\u308a\u8a00\u300d\u3060\u308d","id":41190073227550720,"from_user_id":49219631,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"98560114","profile_image_url":"http://a0.twimg.com/profile_images/1252332545/IMGP8170_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:32 +0000","from_user":"qess0093","id_str":"41190070706905088","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30b7\u30e5\u30fc\u30c6\u30a3\u304f\u305d\u3046\u305c\u3048\uff57 RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41190070706905088,"from_user_id":98560114,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"197459334","profile_image_url":"http://a3.twimg.com/profile_images/1210698414/shiratorishoko_normal.png","created_at":"Fri, 25 Feb 2011 17:37:31 +0000","from_user":"SyokoShiratori","id_str":"41190064243478528","metadata":{"result_type":"recent"},"to_user_id":null,"text":"+0.50kg \u540c\u3058\u304f\u30c0\u30a4\u30a8\u30c3\u30c8\u4e2d\u3067\u3059\u3002\u3088\u304f\u3053\u306e\u30b5\u30a4\u30c8\u3067\u4f53\u91cd\u5831\u544a\u3057\u3066\u307e\u3059\u266a http://bit.ly/fhN2fM RT @msophiah \u3046\u3046\u3046\u30fb\u30fb\u30fb\u304a\u8179\u3059\u3044\u305f\u301c\u30fb\u30fb\u30fb\u6211\u6162\u3001\u6211\u6162\u3001\u6211\u6162\u3002\u30c0\u30a4\u30a8\u30c3\u30c8\u3001\u30c0\u30a4\u30a8\u30c3\u30c8\u3001\u30c0\u30a4\u30a8\u30c3\u30c8\u3002","id":41190064243478528,"from_user_id":197459334,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mob-mc.com" rel="nofollow">\uff08\u4eee\u79f0\uff09\u30c4\u30a4\u30af\u30ea\u30c3\u30af twiclick</a>"},{"from_user_id_str":"180410237","profile_image_url":"http://a3.twimg.com/profile_images/1254473979/icon_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:30 +0000","from_user":"ka_ph","id_str":"41190062184079360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u5b9a\u671fpost\u3011\u30d5\u30a7\u30eb\u30c7\u30a3\u30ca\u30f3\u30c8bot( http://twitter.com/ferdinand_bot )\u4f5c\u308a\u307e\u3057\u305f\u3002\u304a\u5b50\u69d8\u306e\u540d\u524d\u304a\u501f\u308a\u3055\u305b\u3066\u304f\u308c\u308b\u65b9\u3044\u307e\u3057\u305f\u3089@ka_ph\u307e\u3067\u304a\u9858\u3044\u3057\u307e\u3059\u3002","id":41190062184079360,"from_user_id":180410237,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"52283906","profile_image_url":"http://a3.twimg.com/profile_images/387644016/10100654519_s_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:26 +0000","from_user":"rolling_bean","id_str":"41190043313913856","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3081\u307e\u3044\u304c\u3057\u307e\u3059\u306d\u301cRT @yurikalin:\u30b3\u30a4\u30c4\u30e9\u5168\u54e1\u3044\u306a\u304f\u306a\u3063\u305f\u3089\u3001\u660e\u308b\u304f\u306a\u308b\u3060\u308d\u3046\u306a\u3041\uff5e\u266a\uff1e\u65e5\u672c\u306e\u30d3\u30b8\u30e7\u30f3 RT roll \u65e5\u7d4c\uff06CSIS\u30b7\u30f3\u30dd\u30b8\u30a6\u30e0\u300c\u5b89\u4fdd\u6539\u5b9a50\u5468\u5e74\u3001\u3069\u3046\u306a\u308b\u65e5\u7c73\u95a2\u4fc2\u300d http://bit.ly/dES8PY\u3000http://bit.ly/ihg0GT","id":41190043313913856,"from_user_id":52283906,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tabtter.jp" rel="nofollow">\u30bf\u30d6\u30c3\u30bf\u30fc</a>"},{"from_user_id_str":"351896","profile_image_url":"http://a3.twimg.com/profile_images/1179865336/icon12911887173020_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:26 +0000","from_user":"cicada","id_str":"41190043292925952","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4e2d\u5b66\u53d7\u9a13\u7a0b\u5ea6\u306e\u7b97\u6570\u306e\u554f\u984c\u3092\u51fa\u3059BOT http://twitter.com/arithmetic_bot \u6c17\u306b\u306f\u306a\u308b\u304c\u3001\u3061\u3083\u3093\u3068\u898b\u308b\u65e5\u304c\u6765\u308b\u3060\u308d\u3046\u304b\u30fb\u30fb\u3000#tearai\uff1a\u30ed\u30b3\u30e9\u30dc\u5bae\u5d0e\u770c http://locolabo.com/mz/ #mzlf","id":41190043292925952,"from_user_id":351896,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://locolabo.com/mz/" rel="nofollow">\u30ed\u30b3\u30e9\u30dc\u5bae\u5d0e\u770c</a>"},{"from_user_id_str":"744554","profile_image_url":"http://a1.twimg.com/profile_images/1088753125/11868894_normal.gif","created_at":"Fri, 25 Feb 2011 17:37:20 +0000","from_user":"Febreze","id_str":"41190019020505088","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30cd\u30bf\u30d0\u30ec\u3042\u307e\u308a\u6c17\u306b\u3057\u306a\u3044\u30bf\u30a4\u30d7\u3060\u3051\u3069\u306a\u3093\u304b\u3053\u3046Twitter\u958b\u304f\u3060\u3051\u3067\u30ac\u30f3\u30ac\u30f3\u30cd\u30bf\u30d0\u30ec\u5165\u3063\u3066\u304f\u308b\u306e\u306f\u306a\u3093\u3068\u3082\u8a00\u3048\u306a\u3044\u306a\u3002","id":41190019020505088,"from_user_id":744554,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"203371794","profile_image_url":"http://a1.twimg.com/profile_images/1226537594/___normal.png","created_at":"Fri, 25 Feb 2011 17:37:16 +0000","from_user":"himeko24","id_str":"41190004139114496","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6b21\u3044\u3063\u3066\u307f\u3088\u30fc\u3000\u306f\u3044\u3053\u308c\u3000 \u6fc0\u5b89\u26052010\u5e74\u590f\u65b0\u30c7\u30b6\u30a4\u30f3\u2605\u30bb\u30af\u30b7\u30fc\u306a\u9023\u4f53\u5f0f\u7121\u5730\u6c34\u7740 \u80f8\u30d1\u30c3\u30c9\u4ed8\u304dQ122 http://bit.ly/h72C4i","id":41190004139114496,"from_user_id":203371794,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.google.co.jp" rel="nofollow">himeko24</a>"},{"from_user_id_str":"119988932","profile_image_url":"http://a3.twimg.com/profile_images/1214344633/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:16 +0000","from_user":"7na_love_6sa","id_str":"41190002000007169","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30d6\u30ed\u30b0\u66f4\u65b0\u3057\u307e\u3057\u305f\uff01Twitter\uff06mixi\u304b\u3089\u3082\u30b3\u30e1\u30f3\u30c8\u5b9c\u3057\u304f\u306d\u266a\n\u300c\u30cd\u30a4\u30eb\u30c1\u30a7\u30f3\u30b8\u266a\u300d http://amba.to/hy0Do2","id":41190002000007169,"from_user_id":119988932,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"217408835","profile_image_url":"http://a1.twimg.com/profile_images/1215428655/____4.0157_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:12 +0000","from_user":"nikubenki1123","id_str":"41189985424125952","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @x68k: \u57fa\u672c\u7684\u306bTwitter\u4e0a\u3067\u306f"\u597d\u304d\u306b\u3084\u308c\u3070\u3044\u3044"\u3060\u3051\u3069\u3001\u540d\u524d\u3082\u30a2\u30a4\u30b3\u30f3\u3082\u30a2\u30f3\u30bf\u3058\u3083\u306a\u3044\u305f\u304f\u3055\u3093\u306e\u4eba\u305f\u3061\u306e\u9b42\u304c\u3053\u3082\u3063\u305f\u3082\u306e\u306a\u306e\u3060\u304b\u3089\u3001\u305d\u308c\u3060\u3051\u306f"\u80cc\u8ca0\u3048"\u3068\u601d\u3046\uff1e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8","id":41189985424125952,"from_user_id":217408835,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tweetlogix.com" rel="nofollow">Tweetlogix</a>"},{"from_user_id_str":"139137996","profile_image_url":"http://a0.twimg.com/profile_images/1087408006/cut_work_18_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:12 +0000","from_user":"fujiokayouko","id_str":"41189984354566144","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u591c\u4e2d\u306bTwitter\u3092\u306a\u3093\u3068\u306a\u304f\u8997\u3044\u305f\u3089\u3082\u306e\u3059\u3054\u3044\u307e\u3069\u30de\u30aeTL\u3067","id":41189984354566144,"from_user_id":139137996,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mobile.twitter.com" rel="nofollow">Mobile Web</a>"},{"from_user_id_str":"61221002","profile_image_url":"http://a3.twimg.com/profile_images/554916301/_1259757374_61_normal.png","created_at":"Fri, 25 Feb 2011 17:37:08 +0000","from_user":"hiromk63","id_str":"41189970613903360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @kenji_kohashi \u7121\u4e8b\u6620\u753b\u88fd\u4f5c\u306e\u5831\u544a\u306f\u3067\u304d\u305f\u3051\u3069\u4eca\u3060\u7de8\u96c6\u306f\u7d9a\u3044\u3066\u307e\u3059w \u305d\u3093\u306a\u3068\u3053\u3067 \u6620\u753b\u300cDON'T STOP!\u300d\u306eTwitter \u30a2\u30ab\u30a6\u30f3\u30c8 @DONTSTOPMOVIE \u3082\u958b\u59cb\u3001\u3082\u3057\u826f\u304b\u3063\u305f\u3089\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u304f\u3060\u3055\u3044\uff01\u50d5\u3082\u542b\u3081\u6620\u753b\u88fd\u4f5c\u95a2\u4fc2\u8005\u304c\u6c17\u9577\u306b\u3064\u3076\u3084\u304d\u307e\u3059","id":41189970613903360,"from_user_id":61221002,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"147393812","profile_image_url":"http://a1.twimg.com/profile_images/1114001122/hana_10_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:07 +0000","from_user":"tubasa_uki","id_str":"41189965924667392","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\uff10\uff10\uff17\u3082\u3073\u3063\u304f\u308a\u3000\u5927\u56fd\u306e\u5927\u7d71\u9818\u9078\u304b\u3089\u3000\u5cf6\u56fd\u306e\u5730\u65b9\u9078\u306e\u9078\u6319\u307e\u3067\u306b\u3082\u3000\u6697\u8e8d\u3057\u3066\u3044\u308b\uff3e\uff3e\u3000\u3053\u306eTwitter \u30b9\u30ad\u30e3\u30f3\u30c0\u30eb\u3084\u60aa\u8cea\u306a\u4e8b\u4ef6\u306b\u3082\u7d61\u3080\u304c\u3000Twitter\u304b\u3089\u767a\u4fe1\u3055\u308c\u305f\u3000\u5e73\u548c\u3078\u306e\u8ca2\u732e\u306f\u3000\u307e\u3055\u306b\u30ce\u30fc\u3079\u30eb\u5e73\u548c\u8cde\u3082\u306e http://bit.ly/esjWDG #dotubo_ss","id":41189965924667392,"from_user_id":147393812,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"96081746","profile_image_url":"http://a0.twimg.com/profile_images/1244505419/illust832_normal.png","created_at":"Fri, 25 Feb 2011 17:37:07 +0000","from_user":"kazukt","id_str":"41189963131387904","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3046\u308b\u304a\u307c\u7d75\u3001\u4ed6\u306e\u4eba\u306e\u3082\u898b\u3066\u3044\u305f\u3089\u3084\u305f\u3089\u30de\u30f3\u30ac\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u3067\u3080\u3061\u3083\u304f\u3061\u3083\u4e0a\u624b\u3044\u4eba\u304c\uff01\u2026\u3068\u3001\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u898b\u305f\u3089\u3001\u306a\u3093\u3068\u3054\u672c\u4eba\u304c\u66f8\u3044\u3066\u3044\u3089\u3063\u3057\u3083\u3063\u305f\u3002Twitter\u3063\u3066\u30b9\u30b4\u30a4\u308f\u3002","id":41189963131387904,"from_user_id":96081746,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://janetter.net/" rel="nofollow">Janetter</a>"},{"from_user_id_str":"86306230","profile_image_url":"http://a1.twimg.com/profile_images/593004766/j2j_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:03 +0000","from_user":"excite_j2j","id_str":"41189949927596032","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u79c1\u306f\u3001\u65e9\u7a32\u7530\u5927\u5b66\u30aa\u30fc\u30d7\u30f3\u30ab\u30ec\u30c3\u30b8\u306e\u5b66\u751f\u306e\u8003\u3048\u3066\u3044\u308b\u3001\u5352\u696d\u751fSoudai /\u65e9\u7a32\u7530\u30ab\u30fc\u30c9\u4f1a\u54e1/ Soudai\u5b66\u751f\u89aa/\u3001\u8ab0\u304b\u304c\u30aa\u30fc\u30d7\u30f3\u30ab\u30ec\u30c3\u30b8\u65e9\u7a32\u7530\u5927\u5b662000\u5186\u306e\u5165\u5834\u6599\u306e\u30e1\u30f3\u30d0\u30fc\u3092\u7d39\u4ecb\u3057\u3066\u304f\u308c\u305f\u65b9\u304c\u305a\u3063\u3068\u5b89\u4e0a\u304c\u308a\u3060\u3002 (\u5143\u767a\u8a00 http://bit.ly/esxiwT )","id":41189949927596032,"from_user_id":86306230,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://d.hatena.ne.jp/fn7" rel="nofollow">\u65e5\u672c\u8a9e\u65e5\u672c\u8a9e\u7ffb\u8a33\u30b8\u30a7\u30cd\u30ec\u30fc\u30bf</a>"},{"from_user_id_str":"120927161","profile_image_url":"http://a0.twimg.com/profile_images/1230006483/20110131_13022_26776_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:00 +0000","from_user":"FRISKFOSSILFANG","id_str":"41189933855158272","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41189933855158272,"from_user_id":120927161,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"228973151","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:36:59 +0000","from_user":"daisuke1589","id_str":"41189931887890432","metadata":{"result_type":"recent"},"to_user_id":null,"text":"twitter\u3063\u3066\u52dd\u624b\u306b\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u3082\u3044\u3044\u3093\u3060\u3063\u3051\uff1f","id":41189931887890432,"from_user_id":228973151,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"54314110","profile_image_url":"http://a2.twimg.com/profile_images/1193541240/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:57 +0000","from_user":"Alohazuki","id_str":"41189922668953600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u306e\u5e83\u5cf6\u5f01\u3082\u3042\u3063\u305f\u3093\u3060\u306d\u3002","id":41189922668953600,"from_user_id":54314110,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"72594681","profile_image_url":"http://a3.twimg.com/profile_images/1227240916/____normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:56 +0000","from_user":"uri4ichi","id_str":"41189916922744832","metadata":{"result_type":"recent"},"to_user_id":226852303,"text":"@7_fuka Twitter\u304b\u3076\u308c\u306f\u3001\u3059\u3050\u306bD\u306b\u8d70\u308b\u306e\u3067\u3002\u306a\u3093\u3060\u304b\u5fae\u7b11\u307e\u3057\u3044\u306e\u3067\u3059( \u2579\u25e1\u2579)","id":41189916922744832,"from_user_id":72594681,"to_user":"7_fuka","geo":null,"iso_language_code":"ja","to_user_id_str":"226852303","source":"<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>"},{"from_user_id_str":"168393854","profile_image_url":"http://a3.twimg.com/profile_images/1253554518/GuNp3xVS_normal","created_at":"Fri, 25 Feb 2011 17:36:55 +0000","from_user":"makonyanhime","id_str":"41189913701515264","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6589\u85e4\u3055\u3093\u3082\u30c0\u30e1\u3060...\u4eca\u591c\u306fTwitter\u5909\u3060\u306a\u3041(;_;)","id":41189913701515264,"from_user_id":168393854,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mobile.twitter.com" rel="nofollow">Twitter for Android</a>"},{"from_user_id_str":"122636787","profile_image_url":"http://a2.twimg.com/profile_images/1189607563/DSC01987_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:54 +0000","from_user":"enpy1217","id_str":"41189908500594688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"twitter\u4e45\u3057\u3076\u308a\u306b\u958b\u3044\u305f\u3002\u3068\u3066\u3082\u591a\u5fd9\u3060\u3063\u305f\u3002\u75b2\u308c\u305f\u3002\u304a\u98a8\u5442\u306b\u3082\u5165\u308c\u306a\u304b\u3063\u305f\u3002\u30ad\u30bf\u30cd\u2026","id":41189908500594688,"from_user_id":122636787,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"81663694","profile_image_url":"http://a3.twimg.com/profile_images/1177576126/__normal.png","created_at":"Fri, 25 Feb 2011 17:36:51 +0000","from_user":"progmiya","id_str":"41189895494049792","metadata":{"result_type":"recent"},"to_user_id":94050844,"text":"@hirasai_skyhigh \u6674\u308c\u541b\u3002\u30cd\u30bf\u30d0\u30ec\u306f\u898b\u305f\u304f\u306a\u3044\u3051\u3069\u30012ch\u3082twitter\u3082\u3084\u308a\u305f\u3044\u306e\u304c\u4eba\u3068\u8a00\u3046\u3082\u306e\u3088","id":41189895494049792,"from_user_id":81663694,"to_user":"hirasai_skyhigh","geo":null,"iso_language_code":"ja","to_user_id_str":"94050844","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"159237469","profile_image_url":"http://a3.twimg.com/profile_images/1140433484/______2_normal.png","created_at":"Fri, 25 Feb 2011 17:36:50 +0000","from_user":"hikari_juku","id_str":"41189892096532480","metadata":{"result_type":"recent"},"to_user_id":135634241,"text":"@sssukimasuky \n\u4f55\u304b\u3042\u3063\u305f\u98a8\u3067\u3059\u306d\uff08\u7b11\uff09\u3000\u78ba\u304b\u306bTwitter\u306f\u6c17\u8efd\u3067\u3059\u3057\u306d\u3002\u30e1\u30fc\u30eb\u306b\u306a\u308b\u3068\u30d5\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u91cd\u304f\u306a\u308b\u5834\u5408\u3082\u3042\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u306d\u3002\u305d\u3046\u8003\u3048\u308b\u3068\u3059\u3054\u3044\u6642\u4ee3\u3060\u3002","id":41189892096532480,"from_user_id":159237469,"to_user":"sssukimasuky","geo":null,"iso_language_code":"ja","to_user_id_str":"135634241","source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"141915990","profile_image_url":"http://a0.twimg.com/profile_images/1248969898/icon679566266564378764images_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:48 +0000","from_user":"adashino_","id_str":"41189886878949376","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41189886878949376,"from_user_id":141915990,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"111308629","profile_image_url":"http://a1.twimg.com/profile_images/1137421845/mmooton_normal.png","created_at":"Fri, 25 Feb 2011 17:36:46 +0000","from_user":"mmooton","id_str":"41189877940748288","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @minponjp: \u3010\u3064\u3076\u3084\u304f\u3060\u3051\u306710000\u5186\u5546\u54c1\u5238GET\u3011<<visa\u30ae\u30d5\u30c8\u30ab\u30fc\u30c910000\u5186\u5206\u3092\u6bce\u6708\u62bd\u9078\u3067\u30d7\u30ec\u30bc\u30f3\u30c8>> \u21d2\u8a73\u3057\u304f\u306f\u4e0b\u306e\uff35\uff32\uff2c\u3088\u308a\u2193\u2193\u2193\u2193\u2193 http://minpon.jp/user_data/twitter_campaign.php","id":41189877940748288,"from_user_id":111308629,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"140945098","profile_image_url":"http://a0.twimg.com/profile_images/1198948281/b7664c71-87bc-4187-9d46-a61ab8d41b96_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:46 +0000","from_user":"waruimayuko","id_str":"41189877122867200","metadata":{"result_type":"recent"},"to_user_id":113371008,"text":"@toumeisyoujyo \u3042\u3053\u3061\u3083\u3093Twitter\u3084\u3063\u3066\u305f\u306e\u306d\u3002\u307e\u3060\u304a\u5e2d\u3042\u308b\u305d\u3046\u306a\u306e\u3067\u662f\u975e\uff01","id":41189877122867200,"from_user_id":140945098,"to_user":"toumeisyoujyo","geo":null,"iso_language_code":"ja","to_user_id_str":"113371008","source":"<a href="http://twimi.jp/?r=via" rel="nofollow">twimi\u2606new</a>"},{"from_user_id_str":"167512527","profile_image_url":"http://a1.twimg.com/profile_images/1172286365/newspaper_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:45 +0000","from_user":"KoranKaget","id_str":"41189871775252480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://bit.ly/93Eeud RT @motocentrism \u30d6\u30ed\u30b0\u8a18\u4e8b\u66f8\u304d\u307e\u3057\u305f\u30fc\uff1a MotoGP\u3000\u30d6\u30c3\u30af\u30e1\u30fc\u30ab\u30fc\u306b\u898b\u308b\u5404\u30e9\u30a4\u30c0\u30fc\u306e\u4e0b\u99ac\u8a55 - http://goo.gl/xVe6... http://bit.ly/hDYxyx @motogpudpate","id":41189871775252480,"from_user_id":167512527,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"160251772","profile_image_url":"http://a3.twimg.com/profile_images/1150692471/_____normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:45 +0000","from_user":"keikochaki","id_str":"41189870781075456","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300c\u305a\u3063\u3068twitter\u3084\u3063\u3066\u308b\u3088\u306d\u300d\u3068\u6012\u3089\u308c\u3066\u3057\u307e\u3063\u305f(\u82e6\u7b11)","id":41189870781075456,"from_user_id":160251772,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twtr.jp" rel="nofollow">Keitai Web</a>"},{"from_user_id_str":"211565766","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:36:42 +0000","from_user":"sayap1yo","id_str":"41189858236043264","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u304a\u98df\u4e8b\u4f1a\u884c\u304d\u305f\u304b\u3063\u305f\u3051\u3069\n\u53cb\u9054\u3068\u904a\u3093\u3067\u307e\u3093\u305f\ue056\ue326\n\nTwitter\u898b\u3066\u307e\u3057\u305f\u3051\u3069\n\u3064\u3076\u3084\u304f\u30bf\u30a4\u30df\u30f3\u30b0\n\u5931\u3063\u3066\u305f\u3060\u3051\u3067\u3059( \u00b4 \u25bd ` )\uff89\u7b11","id":41189858236043264,"from_user_id":211565766,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.nibirutech.com" rel="nofollow">TwitBird</a>"},{"from_user_id_str":"19603191","profile_image_url":"http://a1.twimg.com/profile_images/1254077264/116_normal.gif","created_at":"Fri, 25 Feb 2011 17:36:40 +0000","from_user":"Purple_Flash","id_str":"41189851873157120","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41189851873157120,"from_user_id":19603191,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"215930291","profile_image_url":"http://a0.twimg.com/profile_images/1247906106/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:30 +0000","from_user":"minori_millie","id_str":"41189810055938048","metadata":{"result_type":"recent"},"to_user_id":212972774,"text":"@c_c_chika \u7b11\u3063\u3066\u305d\u3046\u3060\u306a\u3063\u3066\u601d\u3063\u3066\u305f(o^^o)\u30c1\u30ab\u306e\u7b11\u3044\u58f0\u304c\u805e\u3053\u3048\u3066\u304d\u305f\u3082\u3093\u3002mail\u306bTwitter\u3067\u5927\u5fd9\u3057\u3084\u3002","id":41189810055938048,"from_user_id":215930291,"to_user":"c_c_chika","geo":null,"iso_language_code":"ja","to_user_id_str":"212972774","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"197459334","profile_image_url":"http://a3.twimg.com/profile_images/1210698414/shiratorishoko_normal.png","created_at":"Fri, 25 Feb 2011 17:36:30 +0000","from_user":"SyokoShiratori","id_str":"41189809586311168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"+0.90kg \u30c0\u30a4\u30a8\u30c3\u30c8\u5fdc\u63f4\u3057\u3066\u307e\u3059\u3002(*^^*)\u30c0\u30a4\u30a8\u30c3\u30c8\u4f53\u91cd\u5831\u544a\u306e\u3064\u3076\u3084\u304d\u3067\u3059\u3002 http://bit.ly/fhN2fM RT @hayayumi \u3053\u3093\u306a\u6642\u9593\u306b\u3084\u304d\u306b\u304f\u30fc\u266b\u30c0\u30a4\u30a8\u30c3\u30c8\u671f\u9593\u306a\u306e\u306b\u306d....","id":41189809586311168,"from_user_id":197459334,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mob-mc.com" rel="nofollow">\uff08\u4eee\u79f0\uff09\u30c4\u30a4\u30af\u30ea\u30c3\u30af twiclick</a>"},{"from_user_id_str":"12337665","profile_image_url":"http://a0.twimg.com/profile_images/1146194926/pixiv-icon_normal.png","created_at":"Fri, 25 Feb 2011 17:36:27 +0000","from_user":"t_a_k_i","id_str":"41189797364121600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Google\u30ea\u30fc\u30c0\u30fc\u3067\u30b5\u30a4\u30c8\u306e\u66f4\u65b0\u30c1\u30a7\u30c3\u30af\u3059\u308b\u3088\u308a\u3001Twitter\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u66f4\u65b0\u3092\u77e5\u308b\u307b\u3046\u304c\u4fbf\u5229\u3060\u306a\u3053\u308c","id":41189797364121600,"from_user_id":12337665,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>"},{"from_user_id_str":"104862453","profile_image_url":"http://a3.twimg.com/profile_images/1248609864/Image014_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:25 +0000","from_user":"yuz_ume","id_str":"41189787943714816","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41189787943714816,"from_user_id":104862453,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"213846746","profile_image_url":"http://a1.twimg.com/profile_images/1242263342/haruhi1_normal.png","created_at":"Fri, 25 Feb 2011 17:36:23 +0000","from_user":"sloth888jpgame","id_str":"41189778409922560","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u643a\u5e2f\u96fb\u8a71\u7528\u306eTwitter\u3092\u5229\u7528\u3057\u305f\u30b2\u30fc\u30e0\u3092\u77e5\u3063\u3066\u3044\u308b\u4eba\u306f\u3001\u7d39\u4ecb\u3057\u3066\u304f\u3060\u3055\u3044\u3002 #TwitterGame","id":41189778409922560,"from_user_id":213846746,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"17484724","profile_image_url":"http://a2.twimg.com/profile_images/1138677235/iconue_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:22 +0000","from_user":"tsutcho","id_str":"41189777831231490","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30aa\u30b7\u30de\u3055\u3093twitter\u306b\u7acb\u3064\u30fb\u30fb\u30fb\u3060\u3068\u30fb\u30fb\u30fb\uff1f\uff12\u756a\u76ee\u306e\u30d5\u30a9\u30ed\u30ef\u30fc\u306e\u5ea7\u3092\u3044\u305f\u3060\u3044\u3066\u304a\u3053\u3046","id":41189777831231490,"from_user_id":17484724,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"220041064","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:36:21 +0000","from_user":"sloth888jp_bot5","id_str":"41189772521254914","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6642\u3005\u3001TwiAll\uff08\u30c4\u30a4\u30aa\u30fc\u30eb\uff09\u3067Twitter\u306e\u81ea\u52d5\u30d5\u30a9\u30ed\u30fc\u30fb\u30d5\u30a9\u30ed\u30fc\u8fd4\u3057\u3092\u3057\u3066\u3044\u307e\u3059\u3002","id":41189772521254914,"from_user_id":220041064,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"177693537","profile_image_url":"http://a0.twimg.com/profile_images/1240130924/20110207213206_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:21 +0000","from_user":"Na_Okinawa","id_str":"41189769912397824","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @ebizo66: \u30ea\u30d3\u30a2\u30fb\u30c8\u30ea\u30dd\u30ea\u306eTw\uff1a\u6551\u6025\u8eca\u304c\u6765\u305f\u304c\u3001\u8ca0\u50b7\u8005\u3092\u8eca\u5185\u3067\u6bba\u5bb3\u3057\u3066\u3044\u305f\u3001\u3068\u3002\uff08\u6ec5\u8336\u82e6\u8336\u3060\uff01\uff09http://ow.ly/43pQ2 #libjp","id":41189769912397824,"from_user_id":177693537,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"147006592","profile_image_url":"http://a2.twimg.com/profile_images/1251306448/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:19 +0000","from_user":"takasu_rika","id_str":"41189763532865536","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @kihirokiro: Twitter\u3067\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u3044\u3063\u3066\u3082\u5143\u3005Twitter\u3063\u3066\u300c\u500b\u4eba\u306e\u72ec\u308a\u8a00\u300d\u3060\u308d","id":41189763532865536,"from_user_id":147006592,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"100239985","profile_image_url":"http://a1.twimg.com/profile_images/733461294/CIMG0207_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:19 +0000","from_user":"strangebarjun","id_str":"41189762182152192","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u3092\u59cb\u3081\u3066\u3001\u305d\u308d\u305d\u308d\u4e00\u5e74\u306b\u306a\u308a\u307e\u3059\u3002\u632f\u308a\u8fd4\u308b\u3068\u3001\u307c\u304f\u306e\u4eba\u9593\u6027\u3092\u305d\u3063\u304f\u308a\u53cd\u6620\u3059\u308b\u304c\u5982\u304f\u3001\u534a\u7aef\u3067\u3059\u306d\u3002\u60c5\u5831\u53ce\u96c6\u30c4\u30fc\u30eb\u3001\u60c5\u5831\u767a\u4fe1\u30c4\u30fc\u30eb\u3001\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3\u30c4\u30fc\u30eb\u3001\u3069\u308c\u3082\u6a5f\u80fd\u3057\u5207\u308c\u3066\u3044\u306a\u3044\u306a\u3042\u3001\u3068\u3002\u305d\u3057\u3066\u3042\u308b\u306e\u306f\u300c\u3069\u3053\u304b\u3089\u3082\u76f8\u624b\u306b\u3055\u308c\u3066\u3044\u306a\u3044\u300d\u3068\u3044\u3046\u3001\u65e2\u77e5\u306e\u73fe\u5b9f\u3067\u3059\u3002","id":41189762182152192,"from_user_id":100239985,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"126390384","profile_image_url":"http://a2.twimg.com/profile_images/1176065038/nemunemu_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:18 +0000","from_user":"gesukapper","id_str":"41189757476286464","metadata":{"result_type":"recent"},"to_user_id":80935865,"text":"@tatsugorou \u306a\u3093\u304b\u4e16\u306e\u4e2d\u306b\u306f\u611a\u75f4\u3082\u4e0b\u30cd\u30bf\u3082\u8a00\u3044\u653e\u984c\u306etwitter\u3068\u3044\u3046\u3082\u306e\u304c\u3042\u308b\u305d\u3046\u3067\u3059\u3002","id":41189757476286464,"from_user_id":126390384,"to_user":"tatsugorou","geo":null,"iso_language_code":"ja","to_user_id_str":"80935865","source":"<a href="http://janetter.net/" rel="nofollow">Janetter</a>"},{"from_user_id_str":"196059029","profile_image_url":"http://a1.twimg.com/profile_images/1208831726/ruka2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:17 +0000","from_user":"luka_m_bot","id_str":"41189756666777600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u308f\u305f\u3057\u3082twitter\u306f\u3058\u3081\u307e\u3057\u305f","id":41189756666777600,"from_user_id":196059029,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www24.atpages.jp/aoi2/bot.php" rel="nofollow">\u5de1\u308b\u97f3</a>"},{"from_user_id_str":"88135613","profile_image_url":"http://a3.twimg.com/profile_images/1088552877/P9280150_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:14 +0000","from_user":"Roko38","id_str":"41189740321587200","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\uff46\uff42\u306b\u30ed\u30b0\u30a4\u30f3\u3059\u308b\u6a5f\u4f1a\u304c\u65e5\u306b\u65e5\u306b\u5897\u3048\u3066\u304d\u305f\uff3e\uff3e \u6163\u308c\u3066\u304f\u308b\u3068\u3042\u3063\u3061\u306e\u304c\u9762\u767d\u3044\uff06\u4f7f\u3044\u52dd\u624b\u304c\u3044\u3044\u3088\u3046\u306a\u6c17\u304c\u3059\u308b\u3002\u8907\u5408\u7684\u306b\u8272\u3005\u51fa\u6765\u307e\u3059\u3088\u306d\u2026\u3063\u3066\u3001\u601d\u3063\u305f\u3053\u3068\u3092\u545f\u304f\u306e\u306fTwitter\u3060\u3063\u305f\u308a\u3067\u3059\u304c\u2026(^_^; \u305d\u3057\u3066\u81ea\u5206\u306e\u5834\u5408\u306f\u30c4\u30a4\u3068\u9023\u52d5\u3057\u3065\u3089\u3044\u72b6\u6cc1\u3060\u3063\u305f\u308a\u3067\u2026\u3002","id":41189740321587200,"from_user_id":88135613,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"110825211","profile_image_url":"http://a2.twimg.com/profile_images/1108977866/o_t_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:12 +0000","from_user":"kou_nanjyo","id_str":"41189731941363712","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @x68k: \u57fa\u672c\u7684\u306bTwitter\u4e0a\u3067\u306f"\u597d\u304d\u306b\u3084\u308c\u3070\u3044\u3044"\u3060\u3051\u3069\u3001\u540d\u524d\u3082\u30a2\u30a4\u30b3\u30f3\u3082\u30a2\u30f3\u30bf\u3058\u3083\u306a\u3044\u305f\u304f\u3055\u3093\u306e\u4eba\u305f\u3061\u306e\u9b42\u304c\u3053\u3082\u3063\u305f\u3082\u306e\u306a\u306e\u3060\u304b\u3089\u3001\u305d\u308c\u3060\u3051\u306f"\u80cc\u8ca0\u3048"\u3068\u601d\u3046\uff1e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8","id":41189731941363712,"from_user_id":110825211,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tweetlogix.com" rel="nofollow">Tweetlogix</a>"},{"from_user_id_str":"2095960","profile_image_url":"http://a2.twimg.com/profile_images/1248999075/majiresu2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:10 +0000","from_user":"guldeen","id_str":"41189726945947648","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3042\u308a\u3083\u307e\u3041\u3002\u25bchttp://bit.ly/et4vVa \uff3b\u89d2\u5ddd\u66f8\u5e97\uff3d\u300c\u30b6\u30fb\u30b9\u30cb\u30fc\u30ab\u30fc\u300d\u4f11\u520a\u3078\u3000\u300c\u6dbc\u5bae\u30cf\u30eb\u30d2\u300d\u751f\u3093\u3060\u30e9\u30ce\u30d9\u96d1\u8a8c18\u5e74\u3067\u5e55 via http://twitter.com/lkj777","id":41189726945947648,"from_user_id":2095960,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"164121549","profile_image_url":"http://a1.twimg.com/profile_images/1251758789/m_108-07ae3_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:09 +0000","from_user":"hachi_touhi","id_str":"41189719299727360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30cd\u30bf\u30d0\u30ec\u6c17\u306b\u3057\u3066\u305f\u3089Twitter\u3084\u3063\u3066\u3089\u308c\u306a\u3044ww","id":41189719299727360,"from_user_id":164121549,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twicca.r246.jp/" rel="nofollow">twicca</a>"},{"from_user_id_str":"194494659","profile_image_url":"http://a3.twimg.com/profile_images/1249717822/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:08 +0000","from_user":"tomonattomo","id_str":"41189715415801856","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3046\u308f\u3001\u660e\u65e5\u671d\u304b\u3089\u30d0\u30a4\u30c8\u3084\u306e\u306b\u306a\u3093\u3060\u3053\u306e\u306d\u3075\u304b\u3057\u3002\u3042\u3001\u591c\u66f4\u304b\u3057\u3002\u30d1\u30d4\u30eb\u30b9\u3068BUMP\u3001\u3048\u307f\u3068Twitter\u306eDM\u3057\u3059\u304e\u305f\u306a\u2026","id":41189715415801856,"from_user_id":194494659,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mixi.jp/promotion.pl?id=voice_twitter" rel="nofollow"> mixi \u30dc\u30a4\u30b9 </a>"},{"from_user_id_str":"97224364","profile_image_url":"http://a3.twimg.com/profile_images/1150074355/fb8bcca60d340862c053a756377bfae8_normal.jpeg","created_at":"Fri, 25 Feb 2011 17:36:06 +0000","from_user":"xxxheat","id_str":"41189709174677504","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u5b8c\u5168\u306b\u30d0\u30b0\u3063\u3066\u308borz","id":41189709174677504,"from_user_id":97224364,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"}],"max_id":41190705623732224,"since_id":38643906774044672,"refresh_url":"?since_id=41190705623732224&q=twitter","next_page":"?page=2&max_id=41190705623732224&rpp=100&lang=ja&q=twitter","results_per_page":100,"page":1,"completed_in":0.093336,"warning":"adjusted since_id to 38643906774044672 (), requested since_id was older than allowed -- since_id removed for pagination.","since_id_str":"38643906774044672","max_id_str":"41190705623732224","query":"twitter"}
+ test/json-data/goldens/unicode_2705.json.golden view
@@ -0,0 +1,1 @@+"\u2705"
+ test/json-data/image_obj.json view
@@ -0,0 +1,14 @@+{+ "Image": {+ "Width": 800,+ "Height": 600,+ "Title": "View from 15th Floor",+ "Thumbnail": {+ "Url": "http://www.example.com/image/481989943",+ "Height": 125,+ "Width": 100+ },+ "Animated" : false,+ "IDs": [116, 943, 234, 38793]+ }+}
− test/json-data/test1.json
@@ -1,14 +0,0 @@-{- "Image": {- "Width": 800,- "Height": 600,- "Title": "View from 15th Floor",- "Thumbnail": {- "Url": "http://www.example.com/image/481989943",- "Height": 125,- "Width": 100- },- "Animated" : false,- "IDs": [116, 943, 234, 38793]- }-}
− test/json-data/test2.json
@@ -1,22 +0,0 @@-[- {- "precision": "zip",- "Latitude": 37.7668,- "Longitude": -122.3959,- "Address": "",- "City": "SAN FRANCISCO",- "State": "CA",- "Zip": "94107",- "Country": "US"- },- {- "precision": "zip",- "Latitude": 37.371991,- "Longitude": -122.026020,- "Address": "",- "City": "SUNNYVALE",- "State": "CA",- "Zip": "94085",- "Country": "US"- }-]
− test/json-data/test3.json
@@ -1,1 +0,0 @@-[ ]
− test/json-data/test4.json
@@ -1,1 +0,0 @@-[11 12 13]
− test/json-data/test5.json
@@ -1,1 +0,0 @@-[[[[0.00]]]]
− test/json-data/test6.json
@@ -1,1 +0,0 @@-{"foo":3"bar":4}
− test/json-data/test7.json
@@ -1,1 +0,0 @@-[null, ]
+ test/json-data/twitter_with_hex_vals.json view
@@ -0,0 +1,1 @@+{"results":[{"from_user_id_str":"178045354","profile_image_url":"http://a0.twimg.com/profile_images/1214479381/154722_10100141954893059_808622_55276626_7445050_n_normal.jpg","created_at":"Fri, 25 Feb 2011 17:40:04 +0000","from_user":"ChuriSta_gt","id_str":"41190705623732224","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3072\u3089\u304c\u306a\u306e\u300c\u3064\u300d\u306f\u3082\u3046Twitter\u306e\u300c\u3064\u300d\u3060\uff01","id":41190705623732224,"from_user_id":178045354,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"71746558","profile_image_url":"http://a2.twimg.com/profile_images/591641547/wwd_normal.gif","created_at":"Fri, 25 Feb 2011 17:40:02 +0000","from_user":"fuckkilldiestar","id_str":"41190699571494912","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u306b\u3057\u3066\u3082Twitter\u3084pixiv\u96e2\u308c\u3092\u3069\u3046\u306b\u304b\u3057\u308d\u674f\u4ec1\u30d6\u30eb\u30de","id":41190699571494912,"from_user_id":71746558,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"131230176","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:39:58 +0000","from_user":"proory_bot","id_str":"41190683922546688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30ea\u30cd\u30f3\u30dd\u30fc\u30c1 http://bit.ly/btjqlH","id":41190683922546688,"from_user_id":131230176,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://proory.com/" rel="nofollow">proory tems</a>"},{"from_user_id_str":"120359038","profile_image_url":"http://a1.twimg.com/profile_images/946521484/200805161826000_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:58 +0000","from_user":"tukinosuke","id_str":"41190680835391488","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41190680835391488,"from_user_id":120359038,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"166512109","profile_image_url":"http://a3.twimg.com/profile_images/1224583217/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:50 +0000","from_user":"yurii1129","id_str":"41190649839620096","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4eca\u6c17\u4ed8\u3044\u305f\u2026\u307f\u3043\u304f\u3093\u306eTwitter\u540d\u3001\u3084\u307e\u306d\u3084\u3093(\uffe3\u25c7\uffe3;)","id":41190649839620096,"from_user_id":166512109,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"228999619","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","created_at":"Fri, 25 Feb 2011 17:39:49 +0000","from_user":"takami926","id_str":"41190644793745408","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7530\u539f\u3055\u3093\u3001\u5fdc\u63f4\u3057\u3066\u307e\u3059\u3002WEB\u3082TWITTER\u3082\u62dd\u898b\u3057\u3066\u307e\u3059\u3002\u7530\u539f\u3055\u3093\u304c\u653f\u6cbb\u5bb6\u306b\u306a\u3063\u3066\u3001\u65e5\u672c\u3092\u5909\u3048\u3066\u304f\u3060\u3055\u3044\u3002\u5c16\u95a3\u3001\u5317\u65b9\u554f\u984c\u5171\u306b\u65e5\u672c\u306e\u653f\u6cbb\u306e\u5931\u6557\u3067\u3059\u3002\u8a55\u8ad6\u5bb6\u306f\u8272\u3005\u8a00\u3063\u3066\u307e\u3059\u304c\u3001\u4e2d\u6771\u307b\u3069\u56fd\u6c11\u306e\u71b1\u6c17\u304c\u7121\u304f\u3001\u683c\u5dee\u304c\u3042\u308a\u3001\u4f55\u3082\u5909\u308f\u3089\u306a\u3044\u666f\u6c17\u4f4e\u8ff7\u306e\u65e5\u672c\u306b\u56fd\u6c11\u306f\u8ae6\u3081\u3066\u308b\u3093\u3067\u3059\u3002","id":41190644793745408,"from_user_id":228999619,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"151773701","profile_image_url":"http://a0.twimg.com/profile_images/1213699753/obi_nao_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:44 +0000","from_user":"obi_nao","id_str":"41190622949941248","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3060\u3044\u3076\u5e74\u4e0b\u306e\u5f8c\u8f29\u306b\u3001\u30d3\u30b8\u30cd\u30b9\u3084\u308b\u306a\u3089\u771f\u5263\u306bTwitter\u3084\u308c\uff01\u3063\u3066\u6012\u3089\u308c\u305f\u3002\u306a\u306e\u3067\u4eca\u65e5\u304b\u3089\u771f\u5263\u306b\u3064\u3076\u3084\u304f\u3053\u3068\u306b\u3057\u307e\u3059\u3002\u3088\u308d\u3057\u304f\u3067\u3059\u3002","id":41190622949941248,"from_user_id":151773701,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"20817229","profile_image_url":"http://a0.twimg.com/profile_images/1212012721/205_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:43 +0000","from_user":"allte","id_str":"41190619804082176","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7206\u7b11\u3057\u3066\u547c\u5438\u56f0\u96e3\u3067\u75d9\u6523\u3059\u308b\u5618\u304f\u3093\u304c\u898b\u308c\u308b\u306e\u306fTwitter\u3060\u3051","id":41190619804082176,"from_user_id":20817229,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>"},{"from_user_id_str":"166907967","profile_image_url":"http://a2.twimg.com/profile_images/1250526230/___normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:43 +0000","from_user":"NTTYAHOOOOOOOI","id_str":"41190618235412480","metadata":{"result_type":"recent"},"to_user_id":106469594,"text":"@takahirororo \u3066\u304b\u4f55\u3067twitter\u4e0a\u3067\u30a2\u30c9\u30d0\u30a4\u30b9\u3082\u3089\u3063\u3066\u3093\u306d\u3093\uff57","id":41190618235412480,"from_user_id":166907967,"to_user":"takahirororo","geo":null,"iso_language_code":"ja","to_user_id_str":"106469594","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"82581287","profile_image_url":"http://a0.twimg.com/profile_images/774721566/miyaru2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:38 +0000","from_user":"kine_rahchaos","id_str":"41190598132244480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30aa\u30b7\u30de\u3055\u3093\u304cTwitter\u59cb\u3081\u305f\u3060\u3068\u2026","id":41190598132244480,"from_user_id":82581287,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"136633905","profile_image_url":"http://a2.twimg.com/profile_images/1247161991/yama_normal.png","created_at":"Fri, 25 Feb 2011 17:39:35 +0000","from_user":"yamachi39","id_str":"41190584706285568","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3084\u3063\u3071\u308amixi\u3088\u308atwitter\u306e\u304c\u597d\u304d\u304b\u3082","id":41190584706285568,"from_user_id":136633905,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://jigtwi.jp/?p=1" rel="nofollow">jigtwi</a>"},{"from_user_id_str":"44029295","profile_image_url":"http://a2.twimg.com/profile_images/1112965522/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:32 +0000","from_user":"no2yosee","id_str":"41190572769280000","metadata":{"result_type":"recent"},"to_user_id":97721124,"text":"@hn0345 \u3042\u3001\u500b\u4eba\u7684\u306b\u306f\u4eca\u306ftwitter\u306e\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u306b\u66f8\u3044\u3066\u3042\u308b\u30d6\u30ed\u30b0\u306e\u30e6\u30cb\u30c3\u30c8\u3092\u306e\u3093\u3073\u308a\u3084\u3063\u3066\u307e\u3059w","id":41190572769280000,"from_user_id":44029295,"to_user":"hn0345","geo":null,"iso_language_code":"ja","to_user_id_str":"97721124","source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"149872179","profile_image_url":"http://a0.twimg.com/profile_images/1145770150/Winter11_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:31 +0000","from_user":"xmyyyxx","id_str":"41190566951653376","metadata":{"result_type":"recent"},"to_user_id":95069405,"text":"@rindofu \u653b\u7565\u672c\u3042\u308c\u3070\u3044\u3044\u306e\u306b\u3063\u3066\u601d\u3044\u307e\u3059(T\u03c9T)/~~~ \u79c1\u3082\u76f4\u3057\u305f\u3044\u3068\u3053\u3044\u3063\u3071\u3044\u3060\u3051\u3069\u3001\u3042\u306860\u5e74\u304f\u3089\u3044\u3044\u304d\u3089\u308c\u308b\u306f\u305a\u3060\u3057\u3001\u306e\u3093\u3073\u308a\u76f4\u308c\u3070\u3044\u3044\u306a\u3042 \u304a\u3084\u3059\u307f\u3067\u3059^^\uff01\u308a\u3093\u3055\u3093\u3068twitter\u3067\u4ef2\u826f\u304f\u306a\u308c\u3066\u3088\u304b\u3063\u305f\u3067\u3059\u3063","id":41190566951653376,"from_user_id":149872179,"to_user":"rindofu","geo":null,"iso_language_code":"ja","to_user_id_str":"95069405","source":"<a href="http://twtr.jp" rel="nofollow">Keitai Web</a>"},{"from_user_id_str":"105579892","profile_image_url":"http://a0.twimg.com/profile_images/1212950455/love_happy_pink_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:30 +0000","from_user":"love_happy_pink","id_str":"41190566494601216","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u305d\u308c\u898b\u305f\u3044\u306a\u266aRT @kazukt \u3046\u308b\u304a\u307c\u7d75\u3001\u4ed6\u306e\u4eba\u306e\u3082\u898b\u3066\u3044\u305f\u3089\u3084\u305f\u3089\u30de\u30f3\u30ac\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u3067\u3080\u3061\u3083\u304f\u3061\u3083\u4e0a\u624b\u3044\u4eba\u304c\uff01\u2026\u3068\u3001\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u898b\u305f\u3089\u3001\u306a\u3093\u3068\u3054\u672c\u4eba\u304c\u66f8\u3044\u3066\u3044\u3089\u3063\u3057\u3083\u3063\u305f\u3002Twitter\u3063\u3066\u30b9\u30b4\u30a4\u308f\u3002","id":41190566494601216,"from_user_id":105579892,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.nibirutech.com/" rel="nofollow">TwitBird iPad</a>"},{"from_user_id_str":"16996368","profile_image_url":"http://a0.twimg.com/profile_images/1198892387/pochi_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:30 +0000","from_user":"HyoYoshikawa","id_str":"41190564187611136","metadata":{"result_type":"recent"},"to_user_id":1800565,"text":"@shinichiro_beck \u73fe\u5730\u304b\u3089\u306a\u3089\u826f\u304f\u3066\u4ed6\u306e\u5730\u57df\u304b\u3089\u3060\u4f59\u8a08\u306a\u3089\u3001\u4f55\u306e\u305f\u3081\u306bTwitter\u304c\u3042\u308b\u306e\u304b\u308f\u304b\u3089\u306a\u3044\u3088\u3002\u3044\u307e\u8d77\u304d\u3066\u308b\u3053\u3068\u306e\u8aac\u660e\u3082\u3064\u304b\u306a\u3044\u3002\u30a2\u30eb\u30b8\u30e3\u30b8\u30fc\u30e9\u304c\u4f1d\u3048\u3066\u308b\u3053\u3068\u304c\u5168\u3066\u3058\u3083\u306a\u3044\u3057\u3001\u65e5\u672c\u306eTV\u306f\u4f1d\u3048\u306a\u3044\u3067\u3057\u3087\u3046\u3002\u77e5\u308a\u305f\u304c\u3063\u3066\u308b\u4eba\u3082\u305f\u304f\u3055\u3093\u3044\u308b\u3002","id":41190564187611136,"from_user_id":16996368,"to_user":"shinichiro_beck","geo":null,"iso_language_code":"ja","to_user_id_str":"1800565","source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"119070802","profile_image_url":"http://a2.twimg.com/profile_images/1229773005/346d8435099798113a1326e1ba4949ee_normal.jpeg","created_at":"Fri, 25 Feb 2011 17:39:25 +0000","from_user":"takotako726","id_str":"41190545439207424","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u9b54\u6cd5\u5c11\u5973\u307e\u3069\u304b\u30de\u30ae\u30ab\u306e\u53cd\u97ff\u304ctwitter\u3067\u306f\u3093\u3071\u306d\u3048\u4ef6\u3002","id":41190545439207424,"from_user_id":119070802,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"165695316","profile_image_url":"http://a1.twimg.com/profile_images/681748782/ring_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:21 +0000","from_user":"pandora_shotbar","id_str":"41190526447390720","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300e\u30b7\u30e7\u30c3\u30c8\u30d0\u30fc\u3000\u30d1\u30f3\u30c9\u30e9\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u300f\u30b7\u30e7\u30c3\u30c8\u30d0\u30fc\u3000\u30d1\u30f3\u30c9\u30e9\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u2026\uff5chttp://pandora-twitter.seesaa.net/article/187809936.html","id":41190526447390720,"from_user_id":165695316,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://blog.seesaa.jp/" rel="nofollow">SeesaaBlog</a>"},{"from_user_id_str":"88862311","profile_image_url":"http://a2.twimg.com/profile_images/1182243698/161113_100001897885617_169366_q_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:16 +0000","from_user":"amebaguide","id_str":"41190504926416896","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300e\u30a2\u30e1\u30d6\u30ed\u653b\u7565\u30ac\u30a4\u30c9\u306e\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u300f\u30d6\u30ed\u30b0\u306e\u653b\u7565\u3000\u30c4\u30a4\u30c3\u30bf\u30fc\u306e\u3064\u3076\u3084\u304d\u96c6\uff5chttp://accessup-twitter.seesaa.net/article/187809931.html","id":41190504926416896,"from_user_id":88862311,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://blog.seesaa.jp/" rel="nofollow">SeesaaBlog</a>"},{"from_user_id_str":"186895007","profile_image_url":"http://a2.twimg.com/profile_images/1229610799/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:11 +0000","from_user":"zizikt","id_str":"41190486123356161","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u308c\u306f\u500b\u4eba\u7684\u306b\u306f\u91cd\u5b9d\u3067\u3059\u3002\n\u25c6iPhone&iPad\u5411\u3051Twitter\u30a2\u30d7\u30ea\u300c\u3064\u3044\u3063\u3077\u308b\u300d\u306bEvernote\u3068\u306e\u9023\u643a\u6a5f\u80fd\u3092\u8ffd\u52a0 \nhttp://bit.ly/hPf44u","id":41190486123356161,"from_user_id":186895007,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"132320738","profile_image_url":"http://a3.twimg.com/profile_images/1229760475/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:04 +0000","from_user":"faina_","id_str":"41190453592334336","metadata":{"result_type":"recent"},"to_user_id":167894537,"text":"@gjmorley \u30e2\u30fc\u30ea\u30fc\u3055\u3093\u306e\u7ffb\u8a33\u306e\u8a00\u8449\u306e\u30bb\u30f3\u30b9\u304c\u3059\u304d\u3067\u3059\u3002\u305d\u3057\u3066\u3001Twitter\u3067\u77e5\u308b\u3001\u73fe\u5730\u306e\u4eba\u306e\u76ee\u306e\u529b\u3084\u3001\u60c5\u5831\u3092\u4f1d\u3048\u3066\u304f\u308c\u308b\u7686\u3055\u3093\u306e\u60c5\u71b1\u306b\u611f\u52d5\u3057\u3066\u3044\u307e\u3059\u3002\u611f\u52d5\u3059\u308b\u3063\u3066\u3059\u3054\u3044\u30a8\u30cd\u30eb\u30ae\u30fc\u3067\u3059\uff01\uff01","id":41190453592334336,"from_user_id":132320738,"to_user":"gjmorley","geo":null,"iso_language_code":"ja","to_user_id_str":"167894537","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"24870552","profile_image_url":"http://a3.twimg.com/profile_images/907130634/4_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:03 +0000","from_user":"tana1192","id_str":"41190450480021504","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u500b\u4eba\u7684\u306b\u306f\u3001\u30bf\u30b0\u5f3e\u304d\u3059\u308c\u3070\u3044\u3044\uff08\u5f3e\u3051\u308b\u30c4\u30fc\u30eb\u3092\u4f7f\u3063\u3066Twitter\u3092\u3059\u308c\u3070\u3044\u3044\uff09\u3068\u601d\u3046\u3093\u3060\u3051\u3069\u306a\u3042\u3002\u307f\u3093\u306a\u305d\u308c\u306a\u308a\u306bTwitter\u3084\u308b\u4eba\u3060\u3057\u3001\u30c4\u30fc\u30eb\u9078\u3073\u304f\u3089\u3044\u5e45\u3092\u6301\u3063\u3066\u3084\u3063\u3066\u3082\u3002 \u307e\u3042\u3001\u4ffa\u30a2\u30cb\u30e1\u306f\u89b3\u308b\u89b3\u308b\u8a50\u6b3a\u3059\u308b\u3060\u3051\u306e\u4eba\u3060\u304b\u3089\u95a2\u4fc2\u306a\u3044\u3093\u3060\u3051\u3069\u3082\uff57\uff57\u5b9f\u6cc1\u306f\u697d\u3057\u305d\u3046\u306b\u898b\u3048\u308b\u3088\u3002","id":41190450480021504,"from_user_id":24870552,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"58509646","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png","created_at":"Fri, 25 Feb 2011 17:39:02 +0000","from_user":"kakuyas","id_str":"41190446663344128","metadata":{"result_type":"recent"},"to_user_id":107076877,"text":"@Dayspool \u6df1\u591c\uff12\uff19\u6642\u304f\u3089\u3044\u307e\u3067\u306f\u6bce\u65e5\u55b6\u696d\u3057\u3066\u308b\u306e\u3067\u3001twitter\u3001\u30e1\u30c3\u30bb\u3001PS3\u306a\u3069\u3067\u3088\u3093\u3067\u3051\u308c\u3002\u3053\u3063\u3061\u304b\u3089\u58f0\u304b\u3051\u308b\u3053\u3068\u3082\u3042\u308b\u304b\u3082\u3060\u304c\uff57","id":41190446663344128,"from_user_id":58509646,"to_user":"Dayspool","geo":null,"iso_language_code":"ja","to_user_id_str":"107076877","source":"<a href="http://cheebow.info/chemt/archives/2007/04/twitterwindowst.html" rel="nofollow">Twit for Windows</a>"},{"from_user_id_str":"149128527","profile_image_url":"http://a2.twimg.com/profile_images/1254922702/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:39:00 +0000","from_user":"uni13yoki","id_str":"41190437087748096","metadata":{"result_type":"recent"},"to_user_id":119468594,"text":"@kuro_wr84 \u304a\u308c\u3068\u304a\u524d\u3067Twitter\u3067\u4f1a\u8a71\u3057\u305f\u3089\u3001\u5927\u5909\u306a\u3053\u3068\u306b\u306a\u308b\u306a","id":41190437087748096,"from_user_id":149128527,"to_user":"kuro_wr84","geo":null,"iso_language_code":"ja","to_user_id_str":"119468594","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"18670595","profile_image_url":"http://a2.twimg.com/profile_images/1250674062/ProfilePhoto_normal.png","created_at":"Fri, 25 Feb 2011 17:38:59 +0000","from_user":"nyuuuuun","id_str":"41190436450222080","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3078\u30fc\u3053\u3093\u306a\u306b\u3088\u304f\u4f3c\u308b\u3053\u3068\u3082\u3042\u308b\u3093\u3060\u30fc\nhttp://twitter.com/Re_44/status/35943233016168448\nhttp://twitter.com/3510_misaka/status/36122114821988352","id":41190436450222080,"from_user_id":18670595,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"96267603","profile_image_url":"http://a3.twimg.com/profile_images/1245253473/DSiLL3_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:59 +0000","from_user":"arivis","id_str":"41190433119940608","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://twitter.com/#!/arivis/status/40636755380142080 \u306a\u3093\u3064\u3046\u304b\u3053\u308c\u3067\u8d64\u3063\u3066\u306e\u3082\u3061\u3087\u3063\u3068\u3042\u308c\u3063\u3059\u306d\u3002\u305d\u3057\u3066\u4e88\u671f\u3057\u3066\u3044\u305f\u304b\u306e\u3088\u3046\u3060","id":41190433119940608,"from_user_id":96267603,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"148097776","profile_image_url":"http://a3.twimg.com/profile_images/1166904064/broken-heart_normal.png","created_at":"Fri, 25 Feb 2011 17:38:56 +0000","from_user":"ReajuBreaker_A","id_str":"41190422135058432","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u672c\u57a2\u30d5\u30a9\u30ed\u30fc\u3088\u308d\u3057\u304f\u3067\u3059\u2192 http://twitter.com/ReajuBreaker \uff08\uff20\u3060\u3068\u30ea\u30d7\u30e9\u30a4\u304c\u57cb\u307e\u308b\u305f\u3081\u3001URL\u306b\u3057\u3066\u3042\u308a\u307e\u3059\uff09","id":41190422135058432,"from_user_id":148097776,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.twitter.com/ReajuBreaker" rel="nofollow">\u73fe\u5145\u6bba\u3057\u306e\u7121\u4eba\u9023\u545f\uff1c\u30aa\u30fc\u30c8\u30c4\u30a4\u30fc\u30c8\uff1e</a>"},{"from_user_id_str":"59711654","profile_image_url":"http://a2.twimg.com/profile_images/416212928/flowers-06-1_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:56 +0000","from_user":"agamo45","id_str":"41190421522546688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @ebizo66: \u30ea\u30d3\u30a2\u30fb\u30c8\u30ea\u30dd\u30ea\u306eTw\uff1a\u6551\u6025\u8eca\u304c\u6765\u305f\u304c\u3001\u8ca0\u50b7\u8005\u3092\u8eca\u5185\u3067\u6bba\u5bb3\u3057\u3066\u3044\u305f\u3001\u3068\u3002\uff08\u6ec5\u8336\u82e6\u8336\u3060\uff01\uff09http://ow.ly/43pQ2 #libjp","id":41190421522546688,"from_user_id":59711654,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"145311373","profile_image_url":"http://a3.twimg.com/profile_images/1187802576/a_gam_02_normal.png","created_at":"Fri, 25 Feb 2011 17:38:55 +0000","from_user":"nogic1008","id_str":"41190418141937664","metadata":{"result_type":"recent"},"to_user_id":88117317,"text":"@runasoru \u307e\u3042\u5acc\u306a\u3089\u6df1\u591c\u5e2f\u306bTwitter\u898b\u306a\u304d\u3083\u3044\u3044\u3060\u3051\u3067\u3059\u304b\u3089\u306d\u30fc \u30103/19BDM\u30aa\u30d5http://twvt.us/bdoff_kansai\u3011","id":41190418141937664,"from_user_id":145311373,"to_user":"runasoru","geo":null,"iso_language_code":"ja","to_user_id_str":"88117317","source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"195851300","profile_image_url":"http://a2.twimg.com/profile_images/1124572815/be7b4c0a06cb60e8_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:49 +0000","from_user":"LoveLAscrewDoll","id_str":"41190391147540480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @jp_mjp: SCREW TV SHOW Vol.6\u306e\u653e\u9001\u304c\u7121\u4e8b\u306b\u7d42\u4e86\u3044\u305f\u3057\u307e\u3057\u305f\u3002\u3054\u89a7\u9802\u304d\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3057\u305f\uff01\u6b21\u56de\u653e\u9001\u306f3\u670818\u65e5(\u91d1)\u3067\u3059\u3002\u8996\u8074\u8005\u30d7\u30ec\u30bc\u30f3\u30c8\u306e\u8a73\u7d30\u306f\u5f8c\u65e5MJP\u3067\u304a\u77e5\u3089\u305b\u3044\u305f\u3057\u307e\u3059\u3002\u305d\u306e\u969b\u306b\u306f\u3001\u3053\u306eTwitter\u3067\u3082\u304a\u77e5\u3089\u305b\u3044\u305f\u3057\u307e\u3059\u306e\u3067\u3001\u304a\u697d\u3057\u307f\u306b\uff01#SCREWTV","id":41190391147540480,"from_user_id":195851300,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"178045354","profile_image_url":"http://a0.twimg.com/profile_images/1214479381/154722_10100141954893059_808622_55276626_7445050_n_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:48 +0000","from_user":"ChuriSta_gt","id_str":"41190389549510656","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u3053\u4e00\u9031\u9593Twitter\u304c\u3084\u305f\u3089\u697d\u3057\u3044\u306e\u3067\u3059\u3051\u3069\u30fc\u30fc\u30fc\uff01\u306b\u3072\u3072\u3063\u7b11","id":41190389549510656,"from_user_id":178045354,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"50592111","profile_image_url":"http://a0.twimg.com/profile_images/1252176582/lFjpi_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:48 +0000","from_user":"crowNeko","id_str":"41190387271864320","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a8\u30ed\u30b2\u30d7\u30ec\u30a4\u3057\u306a\u304c\u3089\u307e\u3069\u30de\u30aeTL\u3092\u898b\u306a\u3044\u3088\u3046\u306b\u534a\u76ee\u306b\u306a\u308a\u306a\u304c\u3089Twitter\u3057\u3066\u308b\u6df1\u591c2\u6642\u534a\u3002","id":41190387271864320,"from_user_id":50592111,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://stone.com/Twittelator" rel="nofollow">Twittelator</a>"},{"from_user_id_str":"7141467","profile_image_url":"http://a3.twimg.com/profile_images/1198540741/icon12912579345276_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:40 +0000","from_user":"hina_geshi","id_str":"41190355961380864","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u7d50\u5c40\u30cd\u30bf\u30d0\u30ec\u3059\u3093\u306a\u3063\u3066\u8a00\u3046\u65b9\u304c\u30a2\u30ec\u3060\u3088\u306d\u3001\u3057\u306a\u3044\u308f\u3051\u7121\u3044\u3058\u3083\u306a\u3044\u8133\u5185\u5782\u308c\u6d41\u3057\u304cTwitter\u306a\u3093\u3060\u304b\u3089\u3055","id":41190355961380864,"from_user_id":7141467,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://projects.playwell.jp/go/Saezuri" rel="nofollow">Saezuri</a>"},{"from_user_id_str":"149608984","profile_image_url":"http://a0.twimg.com/profile_images/1205950885/090702_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:39 +0000","from_user":"Mr_Tsubaki","id_str":"41190349447774208","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u307e\u3069\u304b\u306fTwitter\u5408\u308f\u305b\u3066\uff11\u6642\u9593\u306f\u697d\u3057\u3044","id":41190349447774208,"from_user_id":149608984,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://z.twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b/twipple</a>"},{"from_user_id_str":"122271550","profile_image_url":"http://a0.twimg.com/profile_images/961936499/neoneko_bot5jpg_____normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:39 +0000","from_user":"neoneko_bot5","id_str":"41190348726345728","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u30c6\u30b9\u30c8\uff1a23\u3011\u4eca\u65e5\u304b\u3089\u5ba3\u4f1d\u958b\u59cb\u2606\u306d\u304a\u306d\u3053\u306eTwitter \u3067 EasyBottex\u3000\u3067\u304d\u308b\u307e\u3067\uff01\u2192http://neoneko.blog31.fc2.com/","id":41190348726345728,"from_user_id":122271550,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www20.atpages.jp/neoneko/" rel="nofollow">neoneko_bot5</a>"},{"from_user_id_str":"127069188","profile_image_url":"http://a3.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","created_at":"Fri, 25 Feb 2011 17:38:37 +0000","from_user":"MYCHEBOT","id_str":"41190340908163074","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30eb\u30d5\u3055\u3093\u304c\u914d\u4fe1\u3092\u7d42\u4e86\u3057\u307e\u3057\u305f\uff01/ http://777labo.com/mychecker/view/745.php / \u30c8\u30d4\u30c3\u30af:XSplit\u30c6\u30b9\u30c8\u3000twitter\u2192http://twitter.com/rukh01","id":41190340908163074,"from_user_id":127069188,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://777labo.com/mychecker/" rel="nofollow">MYCHEBOT</a>"},{"from_user_id_str":"107626142","profile_image_url":"http://a1.twimg.com/profile_images/1104968421/SuperMaika1_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:34 +0000","from_user":"MaikaPaPa","id_str":"41190328614666240","metadata":{"result_type":"recent"},"to_user_id":null,"text":"75\u5e74\u524d\u306e\u4eca\u65e52\u670826\u65e5\u672a\u660e\u3001\u82e5\u304d\u9752\u5e74\u5c06\u6821\u3089\u304c\u653f\u6cbb\u8150\u6557\u3068\u8fb2\u6751\u306e\u56f0\u7aae\u306b\u5bfe\u3057\u3066\u6c7a\u8d77\u3057\u307e\u3057\u305f\u3002\u3082\u3061\u308d\u3093\u5f53\u6642\u306fTwitter\u3082FB\u3082\u3001\u307e\u305f\u5f53\u7136\u306a\u304c\u3089Internet\u3082\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u4e00\u65b9\u3001\u30c1\u30e5\u30cb\u30b8\u30a2\u3001\u30a8\u30b8\u30d7\u30c8\u3001\u4e2d\u6771\u306b\u5e83\u304c\u308b\u53cd\u653f\u5e9c\u30c7\u30e2\u3068\u5f37\u6a29\u4f53\u5236\u306e\u5d29\u58ca\u3002\u73fe\u5728\u306e\u65e5\u672c\u3067\u306f\u8003\u3048\u3089\u308c\u306a\u3044\u3053\u3068\u3067\u3059\u3002","id":41190328614666240,"from_user_id":107626142,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"11111695","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:38:28 +0000","from_user":"kumatchipooh","id_str":"41190306145775617","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @inosenaoki: \u306a\u308b\u307b\u3069\u306d\u3002 RT @dansrmz @inosenaoki \u3053\u3061\u3089\u304c\u30bd\u30d5\u30c8\u30d0\u30f3\u30af\u526f\u793e\u9577\u306e\u677e\u672c\u5fb9\u4e09\u3055\u3093\u306e\u3001Twitter\u306b\u95a2\u3059\u308b\u8ad6\u8003\u3067\u3059\u3002 \u25b6 "Twitter\u306e2\u30c1\u30e3\u30f3\u30cd\u30eb\u5316\u306f\u9632\u6b62\u51fa\u6765\u308b\u304b" http://t.co/Mwzb8Zf","id":41190306145775617,"from_user_id":11111695,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"212161909","profile_image_url":"http://a1.twimg.com/profile_images/1252895790/natm01_normal.gif","created_at":"Fri, 25 Feb 2011 17:38:28 +0000","from_user":"n34hitman","id_str":"41190303830511616","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u30fb\u30d6\u30ed\u30b0\u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8\u81ea\u52d5\u6295.... http://goo.gl/a4RHB 4054","id":41190303830511616,"from_user_id":212161909,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twibow.net/" rel="nofollow">Twibow</a>"},{"from_user_id_str":"105945593","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:38:24 +0000","from_user":"nakano_bot","id_str":"41190285710983168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3053\u306ebot\u306f\u4e0d\u52d5\u7523\u4f1a\u793e\u69d8\u5411\u3051\u306e\u4e0d\u52d5\u7523\u30dd\u30fc\u30bf\u30eb\u30b5\u30a4\u30c8\u3078\u306e\u4e00\u62ec\u8ee2\u9001\uff0bTwitter\u7121\u6599\u8ee2\u9001\u30b5\u30fc\u30d3\u30b9\u306b\u3088\u308a\u3064\u3076\u3084\u304d\u307e\u3059\u3002\u3054\u5229\u7528\u306b\u306a\u308a\u305f\u3044\u5834\u5408\u306f http://bit.ly/demey0 \u306b\u304a\u6c17\u8efd\u306b\u304a\u554f\u3044\u5408\u308f\u305b\u4e0b\u3055\u3044\u3002","id":41190285710983168,"from_user_id":105945593,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.teramax.jp/aboutus.html" rel="nofollow">tmxbot</a>"},{"from_user_id_str":"170904226","profile_image_url":"http://a2.twimg.com/profile_images/1249020397/1789kb_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:21 +0000","from_user":"1789kb","id_str":"41190274428305408","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3068\u308a\u3042\u3048\u305a\u4eca\u56de\u521d\u3081\u3066\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u3067\u898b\u3066\u308f\u304b\u3063\u305f\u306e\u306f\u3001QB\u306f\u5168\u8eab\u304c\u30a2\u30f3\u30d1\u30f3\u30bf\u30a4\u30d7\u3060\u3068\u3044\u3046\u3053\u3068\u3068\u3001\u307e\u3069\u30de\u30ae\u7d42\u4e86\u5f8c\u306eTwitter\u306e\u3056\u308f\u3064\u304d\u304c\u3059\u3054\u3044\u3068\u3044\u3046\u3053\u3068","id":41190274428305408,"from_user_id":170904226,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"166169644","profile_image_url":"http://a1.twimg.com/profile_images/1217017679/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:18 +0000","from_user":"Okkkkkkkkkkun","id_str":"41190262420017152","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3063\u3066Twitter\u3067\u3064\u3076\u3084\u304f\u81ea\u5206\u3082\u76f8\u5f53\u5c0f\u3055\u3044\u306a\u3002","id":41190262420017152,"from_user_id":166169644,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"196623456","profile_image_url":"http://a3.twimg.com/profile_images/1219076661/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:06 +0000","from_user":"NoMoneyClub","id_str":"41190213342601216","metadata":{"result_type":"recent"},"to_user_id":195462431,"text":"@yosal15 \nTwitter\u3084\u3063\u3066\u308b\u3089\u3057\u3044\u3002\u3051\u3069\u3001\u898b\u3064\u304b\u3089\u306a\u3044\u3002","id":41190213342601216,"from_user_id":196623456,"to_user":"yosal15","geo":null,"iso_language_code":"ja","to_user_id_str":"195462431","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"126984048","profile_image_url":"http://a3.twimg.com/profile_images/1254579571/zipyaru-20090829-23-0012_normal.png","created_at":"Fri, 25 Feb 2011 17:38:02 +0000","from_user":"minaduki_naduki","id_str":"41190196418584576","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u203b\u30e1\u30fc\u30eb\u3067\u5973\u306e\u5b50\u53e3\u8aac\u304f\u306e\u306b\u5fd9\u3057\u3044\u3093\u3060\u305d\u3046\u3067\u3059\u3000\u307e\u3058\u3058\u3054\u308d RT @yowano_k: \u5fd9\u3057\u304f\u3066\u3082Twitter\u306b\u9854\u3092\u51fa\u3057\u305f\u304f\u306a\u308b\u50d5\u30a7\u2026\u2026","id":41190196418584576,"from_user_id":126984048,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://seesmic.com/seesmic_desktop/sd2" rel="nofollow">Seesmic Desktop</a>"},{"from_user_id_str":"200568705","profile_image_url":"http://a3.twimg.com/profile_images/1242179765/101230_1355_01_normal.jpg","created_at":"Fri, 25 Feb 2011 17:38:01 +0000","from_user":"hammerstrap","id_str":"41190190428979200","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6628\u65e5\u91d1\u66dc\u65e5\u306f\u732e\u8840\u306b\u5f80\u304f\u3002\u4eca\u306e\u50d5\u306e\u4eba\u9593\u3068\u3057\u3066\u306e\u4fa1\u5024\u306f\u3001\u7cbe\u3005\u3053\u306e\u7a0b\u5ea6\u3002\u8179\u304c\u6e1b\u3063\u305f\u3002\u5374\u8aac\u3002twitter\u306e\u767e\u56db\u5341\u6587\u5b57\u306b\u82db\u3005\u3068\u3057\u3066\u3001\u4e00\u3064\u306e\u4eee\u8aac\u306b\u4fe1\u6191\u6027\u3092\u5f97\u308b\u3002\u6226\u6642\u4e0b\u306e\u7d19\u306e\u7d71\u5236\u3068\u3001\u4e2d\u5cf6\u6566\u306e\u6587\u7ae0\u306e\u95a2\u4fc2\u6027\u3002\u73fe\u5728\u30a6\u30a7\u30d6\u30ed\u30b0\u306b\u3001\u7e8f\u3081\u3066\u3044\u308b\u6700\u4e2d\u3002\u8fd1\u65e5\u516c\u958b\u4e88\u5b9a\u3002","id":41190190428979200,"from_user_id":200568705,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"164970427","profile_image_url":"http://a0.twimg.com/profile_images/1227176662/9192b021ef85ce9902c28955f86e604b_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:59 +0000","from_user":"syuigetsuIT","id_str":"41190184041197569","metadata":{"result_type":"recent"},"to_user_id":141926331,"text":"@iliad_tga \u30a4\u30ea\u30a2\u30b9\u3055\u3093\u304c\u305d\u306e\u8fba\u7406\u89e3\u306e\u3042\u308b\u3053\u3068\u306f\u5206\u304b\u3063\u3066\u307e\u3059\uff57\u3000\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u306ftwitter\u306e\u6c7a\u5b9a\u7684\u306a\u6b20\u70b9\u3060\u3068\u601d\u3044\u307e\u3059\u306d\u3047\u3002","id":41190184041197569,"from_user_id":164970427,"to_user":"iliad_tga","geo":null,"iso_language_code":"ja","to_user_id_str":"141926331","source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"94526795","profile_image_url":"http://a0.twimg.com/profile_images/679411954/akb48_in_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:56 +0000","from_user":"akb48_in","id_str":"41190171248431104","metadata":{"result_type":"recent"},"to_user_id":null,"text":"AKB48\u67cf\u6728\u7531\u7d00 \u304a\u75b2\u308c\u69d8\u3002: \n\u3053\u3093\u3070\u3093\u306f(^O^)\uff0f\u266a\n\u3000\n\u3000\n\u3000\n\u4eca\u65e5\u306e\u516c\u6f14\u697d\u3057\u304b\u3063\u305f\u301c\n\u3000\n\u3000\n\u4e45\u3057\u3076\u308a\u3067\u7dca\u5f35\u3057\u305f\u3051\u3069\u3001\u306f\u3058\u3051\u307e\u304f\u3063\u305f\u305c\u3043\uff01\uff01\n\u3000\n\u3000\n\u3000\nMC\u306f\u565b\u307f\u307e\u304f\u308a\u306e\u30c6\u30f3\u30d1\u308a\u307e\u304f... http://bit.ly/ie8bEa akb48 twitter","id":41190171248431104,"from_user_id":94526795,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"222270374","profile_image_url":"http://a3.twimg.com/profile_images/1250946143/P1040062_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:53 +0000","from_user":"chrxpac","id_str":"41190158455943168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u5b9a\u671f\u3011Twitter\u306f\uff8a\uff9f\uff7f\uff7a\uff9d\u304b\u3089\u3057\u304b\u3067\u304d\u306a\u3044\u306e\u3067\uff98\uff8c\uff9f\u8fd4\u3057\u304c\u9045\u304f\u306a\u308a\u307e\u3059(\u00b4\u30fb\u03c9\u30fb\uff40)\u3054\u4e86\u627f\u4e0b\u3055\u3044!!","id":41190158455943168,"from_user_id":222270374,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"64009258","profile_image_url":"http://a2.twimg.com/profile_images/1154025023/Mixi___normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:52 +0000","from_user":"Tatsuyuko","id_str":"41190153447944192","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4f01\u696d\u304c\u5c31\u6d3b\u751f\u306bFacebook\u3092\u4f7f\u3063\u3066\u7533\u8acb\u305b\u3088\u3068\u3044\u3044\u3001\u4f01\u696d\u304cFacebook\u3092\u4f7f\u3048\u3068\u4f01\u696d\u304c\u8a00\u3063\u3066\u304d\u305f\u308a\u3059\u308c\u3070\u305d\u308c\u3069\u3053\u308d\u3058\u3083\u306a\u3044\u304b\u3068\u3002\u5c11\u306a\u304f\u3068\u3082\u5c31\u6d3b\u3067Twitter\u306e\u8a00\u52d5\u3084\u30d5\u30a9\u30ed\u30ef\u30fc\u3092\u8abf\u67fb\u3059\u308b\u4f01\u696d\u306f\u304b\u306a\u308a\u591a\u3044\u3067\u3059 RT @Isshee: \u4f01\u696d\u3067\u3082\u540c\u3058\u3067\u3057\u3087 RT","id":41190153447944192,"from_user_id":64009258,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"105145175","profile_image_url":"http://static.twitter.com/images/default_profile_normal.png","created_at":"Fri, 25 Feb 2011 17:37:49 +0000","from_user":"snao813","id_str":"41190141703753728","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @yumisaiki: \u795e\u69d8\u306f\u672c\u5f53\u306b\u4eba\u9593\u3092\u3059\u3070\u3089\u3057\u3044\u30d0\u30e9\u30f3\u30b9\u3067\u914d\u7f6e\u3057\u3066\u304a\u3089\u308c\u308b\u3002\u795d\u5cf6\u307f\u305f\u3044\u306a\u5c0f\u3055\u3044\u3068\u3053\u308d\u306b\u306a\u3093\u3067\u3053\u3093\u306a\u306b\u7acb\u6d3e\u306a\u4eba\u304c\u305f\u304f\u3055\u3093\u3044\u308b\u3093\u3060\u308d\u3046\u3002\u795e\u69d8\u3042\u308a\u304c\u3068\u3046\u3002\u672c\u5f53\u306b\u3042\u308a\u304c\u3068\u3046\u3002\u4eba\u9593\u3063\u3066\u3059\u3070\u3089\u3057\u3044\u3068\u601d\u3048\u305f\u3002twitter\u3082\u3042\u308a\u304c\u3068\u3046\u3002\u3000#kaminoseki","id":41190141703753728,"from_user_id":105145175,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://seesmic.com/seesmic_desktop/sd2" rel="nofollow">Seesmic Desktop</a>"},{"from_user_id_str":"203667204","profile_image_url":"http://a2.twimg.com/profile_images/1254664000/eve_blackcat_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:46 +0000","from_user":"eve_blackcat","id_str":"41190129292943361","metadata":{"result_type":"recent"},"to_user_id":146894340,"text":"@kuroiso02 \u3057\u308a\u3068\u308a\u3068\u304b\uff1f\n\u2026\u3067\u3082Twitter\u3060\u3068\u7d42\u308f\u3089\u306a\u304f\u306a\u308b\u30b1\u30c9\u2026","id":41190129292943361,"from_user_id":203667204,"to_user":"kuroiso02","geo":null,"iso_language_code":"ja","to_user_id_str":"146894340","source":"<a href="http://twipple.jp/" rel="nofollow">\u3064\u3044\u3063\u3077\u308b for iPhone</a>"},{"from_user_id_str":"6528403","profile_image_url":"http://a0.twimg.com/profile_images/1240591244/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:45 +0000","from_user":"sortiee","id_str":"41190125924917248","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30cb\u30e1\u5b9f\u6cc1\u306ftwitter\u306e\u764c","id":41190125924917248,"from_user_id":6528403,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sites.google.com/site/peraperaprv/Home" rel="nofollow">P3:PeraPeraPrv</a>"},{"from_user_id_str":"186058304","profile_image_url":"http://a0.twimg.com/profile_images/1250454564/IMG_0210_normal.JPG","created_at":"Fri, 25 Feb 2011 17:37:37 +0000","from_user":"00o8o00","id_str":"41190090386448384","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41190090386448384,"from_user_id":186058304,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"49219631","profile_image_url":"http://a2.twimg.com/profile_images/1231873117/__2-colornow__2__normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:33 +0000","from_user":"irisgazer","id_str":"41190073227550720","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3067\u3059\u3088\u306d\u3047 RT @minamitaiheiyou: \u6545\u306b\u30cd\u30bf\u30d0\u30ec\u3092\u3059\u308b\u306e\u3082\u81ea\u7531\u3002\u30cd\u30bf\u3070\u308c\u3057\u305f\u4eba\u3092\u30c7\u30a3\u30b9\u308b\u306e\u3082\u81ea\u7531\u3002\u3042\u3068\u306f\u5404\u3005\u306e\u88c1\u91cf\u3067\u4e57\u308a\u5207\u3063\u3066\u304f\u3060\u3055\u3044\u3088\u3081\u3093\u3069\u304f\u3055\u3044\u306a RT @kihirokiro: Twitter\u3067\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u3044\u3063\u3066\u3082\u5143\u3005Twitter\u3063\u3066\u300c\u500b\u4eba\u306e\u72ec\u308a\u8a00\u300d\u3060\u308d","id":41190073227550720,"from_user_id":49219631,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"98560114","profile_image_url":"http://a0.twimg.com/profile_images/1252332545/IMGP8170_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:32 +0000","from_user":"qess0093","id_str":"41190070706905088","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30b7\u30e5\u30fc\u30c6\u30a3\u304f\u305d\u3046\u305c\u3048\uff57 RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41190070706905088,"from_user_id":98560114,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sourceforge.jp/projects/tween/wiki/FrontPage" rel="nofollow">Tween</a>"},{"from_user_id_str":"197459334","profile_image_url":"http://a3.twimg.com/profile_images/1210698414/shiratorishoko_normal.png","created_at":"Fri, 25 Feb 2011 17:37:31 +0000","from_user":"SyokoShiratori","id_str":"41190064243478528","metadata":{"result_type":"recent"},"to_user_id":null,"text":"+0.50kg \u540c\u3058\u304f\u30c0\u30a4\u30a8\u30c3\u30c8\u4e2d\u3067\u3059\u3002\u3088\u304f\u3053\u306e\u30b5\u30a4\u30c8\u3067\u4f53\u91cd\u5831\u544a\u3057\u3066\u307e\u3059\u266a http://bit.ly/fhN2fM RT @msophiah \u3046\u3046\u3046\u30fb\u30fb\u30fb\u304a\u8179\u3059\u3044\u305f\u301c\u30fb\u30fb\u30fb\u6211\u6162\u3001\u6211\u6162\u3001\u6211\u6162\u3002\u30c0\u30a4\u30a8\u30c3\u30c8\u3001\u30c0\u30a4\u30a8\u30c3\u30c8\u3001\u30c0\u30a4\u30a8\u30c3\u30c8\u3002","id":41190064243478528,"from_user_id":197459334,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mob-mc.com" rel="nofollow">\uff08\u4eee\u79f0\uff09\u30c4\u30a4\u30af\u30ea\u30c3\u30af twiclick</a>"},{"from_user_id_str":"180410237","profile_image_url":"http://a3.twimg.com/profile_images/1254473979/icon_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:30 +0000","from_user":"ka_ph","id_str":"41190062184079360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3010\u5b9a\u671fpost\u3011\u30d5\u30a7\u30eb\u30c7\u30a3\u30ca\u30f3\u30c8bot( http://twitter.com/ferdinand_bot )\u4f5c\u308a\u307e\u3057\u305f\u3002\u304a\u5b50\u69d8\u306e\u540d\u524d\u304a\u501f\u308a\u3055\u305b\u3066\u304f\u308c\u308b\u65b9\u3044\u307e\u3057\u305f\u3089@ka_ph\u307e\u3067\u304a\u9858\u3044\u3057\u307e\u3059\u3002","id":41190062184079360,"from_user_id":180410237,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"52283906","profile_image_url":"http://a3.twimg.com/profile_images/387644016/10100654519_s_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:26 +0000","from_user":"rolling_bean","id_str":"41190043313913856","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3081\u307e\u3044\u304c\u3057\u307e\u3059\u306d\u301cRT @yurikalin:\u30b3\u30a4\u30c4\u30e9\u5168\u54e1\u3044\u306a\u304f\u306a\u3063\u305f\u3089\u3001\u660e\u308b\u304f\u306a\u308b\u3060\u308d\u3046\u306a\u3041\uff5e\u266a\uff1e\u65e5\u672c\u306e\u30d3\u30b8\u30e7\u30f3 RT roll \u65e5\u7d4c\uff06CSIS\u30b7\u30f3\u30dd\u30b8\u30a6\u30e0\u300c\u5b89\u4fdd\u6539\u5b9a50\u5468\u5e74\u3001\u3069\u3046\u306a\u308b\u65e5\u7c73\u95a2\u4fc2\u300d http://bit.ly/dES8PY\u3000http://bit.ly/ihg0GT","id":41190043313913856,"from_user_id":52283906,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tabtter.jp" rel="nofollow">\u30bf\u30d6\u30c3\u30bf\u30fc</a>"},{"from_user_id_str":"351896","profile_image_url":"http://a3.twimg.com/profile_images/1179865336/icon12911887173020_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:26 +0000","from_user":"cicada","id_str":"41190043292925952","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u4e2d\u5b66\u53d7\u9a13\u7a0b\u5ea6\u306e\u7b97\u6570\u306e\u554f\u984c\u3092\u51fa\u3059BOT http://twitter.com/arithmetic_bot \u6c17\u306b\u306f\u306a\u308b\u304c\u3001\u3061\u3083\u3093\u3068\u898b\u308b\u65e5\u304c\u6765\u308b\u3060\u308d\u3046\u304b\u30fb\u30fb\u3000#tearai\uff1a\u30ed\u30b3\u30e9\u30dc\u5bae\u5d0e\u770c http://locolabo.com/mz/ #mzlf","id":41190043292925952,"from_user_id":351896,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://locolabo.com/mz/" rel="nofollow">\u30ed\u30b3\u30e9\u30dc\u5bae\u5d0e\u770c</a>"},{"from_user_id_str":"744554","profile_image_url":"http://a1.twimg.com/profile_images/1088753125/11868894_normal.gif","created_at":"Fri, 25 Feb 2011 17:37:20 +0000","from_user":"Febreze","id_str":"41190019020505088","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30cd\u30bf\u30d0\u30ec\u3042\u307e\u308a\u6c17\u306b\u3057\u306a\u3044\u30bf\u30a4\u30d7\u3060\u3051\u3069\u306a\u3093\u304b\u3053\u3046Twitter\u958b\u304f\u3060\u3051\u3067\u30ac\u30f3\u30ac\u30f3\u30cd\u30bf\u30d0\u30ec\u5165\u3063\u3066\u304f\u308b\u306e\u306f\u306a\u3093\u3068\u3082\u8a00\u3048\u306a\u3044\u306a\u3002","id":41190019020505088,"from_user_id":744554,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"203371794","profile_image_url":"http://a1.twimg.com/profile_images/1226537594/___normal.png","created_at":"Fri, 25 Feb 2011 17:37:16 +0000","from_user":"himeko24","id_str":"41190004139114496","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6b21\u3044\u3063\u3066\u307f\u3088\u30fc\u3000\u306f\u3044\u3053\u308c\u3000 \u6fc0\u5b89\u26052010\u5e74\u590f\u65b0\u30c7\u30b6\u30a4\u30f3\u2605\u30bb\u30af\u30b7\u30fc\u306a\u9023\u4f53\u5f0f\u7121\u5730\u6c34\u7740 \u80f8\u30d1\u30c3\u30c9\u4ed8\u304dQ122 http://bit.ly/h72C4i","id":41190004139114496,"from_user_id":203371794,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.google.co.jp" rel="nofollow">himeko24</a>"},{"from_user_id_str":"119988932","profile_image_url":"http://a3.twimg.com/profile_images/1214344633/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:16 +0000","from_user":"7na_love_6sa","id_str":"41190002000007169","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30d6\u30ed\u30b0\u66f4\u65b0\u3057\u307e\u3057\u305f\uff01Twitter\uff06mixi\u304b\u3089\u3082\u30b3\u30e1\u30f3\u30c8\u5b9c\u3057\u304f\u306d\u266a\n\u300c\u30cd\u30a4\u30eb\u30c1\u30a7\u30f3\u30b8\u266a\u300d http://amba.to/hy0Do2","id":41190002000007169,"from_user_id":119988932,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"217408835","profile_image_url":"http://a1.twimg.com/profile_images/1215428655/____4.0157_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:12 +0000","from_user":"nikubenki1123","id_str":"41189985424125952","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @x68k: \u57fa\u672c\u7684\u306bTwitter\u4e0a\u3067\u306f"\u597d\u304d\u306b\u3084\u308c\u3070\u3044\u3044"\u3060\u3051\u3069\u3001\u540d\u524d\u3082\u30a2\u30a4\u30b3\u30f3\u3082\u30a2\u30f3\u30bf\u3058\u3083\u306a\u3044\u305f\u304f\u3055\u3093\u306e\u4eba\u305f\u3061\u306e\u9b42\u304c\u3053\u3082\u3063\u305f\u3082\u306e\u306a\u306e\u3060\u304b\u3089\u3001\u305d\u308c\u3060\u3051\u306f"\u80cc\u8ca0\u3048"\u3068\u601d\u3046\uff1e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8","id":41189985424125952,"from_user_id":217408835,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tweetlogix.com" rel="nofollow">Tweetlogix</a>"},{"from_user_id_str":"139137996","profile_image_url":"http://a0.twimg.com/profile_images/1087408006/cut_work_18_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:12 +0000","from_user":"fujiokayouko","id_str":"41189984354566144","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u591c\u4e2d\u306bTwitter\u3092\u306a\u3093\u3068\u306a\u304f\u8997\u3044\u305f\u3089\u3082\u306e\u3059\u3054\u3044\u307e\u3069\u30de\u30aeTL\u3067","id":41189984354566144,"from_user_id":139137996,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mobile.twitter.com" rel="nofollow">Mobile Web</a>"},{"from_user_id_str":"61221002","profile_image_url":"http://a3.twimg.com/profile_images/554916301/_1259757374_61_normal.png","created_at":"Fri, 25 Feb 2011 17:37:08 +0000","from_user":"hiromk63","id_str":"41189970613903360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @kenji_kohashi \u7121\u4e8b\u6620\u753b\u88fd\u4f5c\u306e\u5831\u544a\u306f\u3067\u304d\u305f\u3051\u3069\u4eca\u3060\u7de8\u96c6\u306f\u7d9a\u3044\u3066\u307e\u3059w \u305d\u3093\u306a\u3068\u3053\u3067 \u6620\u753b\u300cDON'T STOP!\u300d\u306eTwitter \u30a2\u30ab\u30a6\u30f3\u30c8 @DONTSTOPMOVIE \u3082\u958b\u59cb\u3001\u3082\u3057\u826f\u304b\u3063\u305f\u3089\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u304f\u3060\u3055\u3044\uff01\u50d5\u3082\u542b\u3081\u6620\u753b\u88fd\u4f5c\u95a2\u4fc2\u8005\u304c\u6c17\u9577\u306b\u3064\u3076\u3084\u304d\u307e\u3059","id":41189970613903360,"from_user_id":61221002,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"147393812","profile_image_url":"http://a1.twimg.com/profile_images/1114001122/hana_10_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:07 +0000","from_user":"tubasa_uki","id_str":"41189965924667392","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\uff10\uff10\uff17\u3082\u3073\u3063\u304f\u308a\u3000\u5927\u56fd\u306e\u5927\u7d71\u9818\u9078\u304b\u3089\u3000\u5cf6\u56fd\u306e\u5730\u65b9\u9078\u306e\u9078\u6319\u307e\u3067\u306b\u3082\u3000\u6697\u8e8d\u3057\u3066\u3044\u308b\uff3e\uff3e\u3000\u3053\u306eTwitter \u30b9\u30ad\u30e3\u30f3\u30c0\u30eb\u3084\u60aa\u8cea\u306a\u4e8b\u4ef6\u306b\u3082\u7d61\u3080\u304c\u3000Twitter\u304b\u3089\u767a\u4fe1\u3055\u308c\u305f\u3000\u5e73\u548c\u3078\u306e\u8ca2\u732e\u306f\u3000\u307e\u3055\u306b\u30ce\u30fc\u3079\u30eb\u5e73\u548c\u8cde\u3082\u306e http://bit.ly/esjWDG #dotubo_ss","id":41189965924667392,"from_user_id":147393812,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"96081746","profile_image_url":"http://a0.twimg.com/profile_images/1244505419/illust832_normal.png","created_at":"Fri, 25 Feb 2011 17:37:07 +0000","from_user":"kazukt","id_str":"41189963131387904","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3046\u308b\u304a\u307c\u7d75\u3001\u4ed6\u306e\u4eba\u306e\u3082\u898b\u3066\u3044\u305f\u3089\u3084\u305f\u3089\u30de\u30f3\u30ac\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u3067\u3080\u3061\u3083\u304f\u3061\u3083\u4e0a\u624b\u3044\u4eba\u304c\uff01\u2026\u3068\u3001\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u898b\u305f\u3089\u3001\u306a\u3093\u3068\u3054\u672c\u4eba\u304c\u66f8\u3044\u3066\u3044\u3089\u3063\u3057\u3083\u3063\u305f\u3002Twitter\u3063\u3066\u30b9\u30b4\u30a4\u308f\u3002","id":41189963131387904,"from_user_id":96081746,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://janetter.net/" rel="nofollow">Janetter</a>"},{"from_user_id_str":"86306230","profile_image_url":"http://a1.twimg.com/profile_images/593004766/j2j_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:03 +0000","from_user":"excite_j2j","id_str":"41189949927596032","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u79c1\u306f\u3001\u65e9\u7a32\u7530\u5927\u5b66\u30aa\u30fc\u30d7\u30f3\u30ab\u30ec\u30c3\u30b8\u306e\u5b66\u751f\u306e\u8003\u3048\u3066\u3044\u308b\u3001\u5352\u696d\u751fSoudai /\u65e9\u7a32\u7530\u30ab\u30fc\u30c9\u4f1a\u54e1/ Soudai\u5b66\u751f\u89aa/\u3001\u8ab0\u304b\u304c\u30aa\u30fc\u30d7\u30f3\u30ab\u30ec\u30c3\u30b8\u65e9\u7a32\u7530\u5927\u5b662000\u5186\u306e\u5165\u5834\u6599\u306e\u30e1\u30f3\u30d0\u30fc\u3092\u7d39\u4ecb\u3057\u3066\u304f\u308c\u305f\u65b9\u304c\u305a\u3063\u3068\u5b89\u4e0a\u304c\u308a\u3060\u3002 (\u5143\u767a\u8a00 http://bit.ly/esxiwT )","id":41189949927596032,"from_user_id":86306230,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://d.hatena.ne.jp/fn7" rel="nofollow">\u65e5\u672c\u8a9e\u65e5\u672c\u8a9e\u7ffb\u8a33\u30b8\u30a7\u30cd\u30ec\u30fc\u30bf</a>"},{"from_user_id_str":"120927161","profile_image_url":"http://a0.twimg.com/profile_images/1230006483/20110131_13022_26776_normal.jpg","created_at":"Fri, 25 Feb 2011 17:37:00 +0000","from_user":"FRISKFOSSILFANG","id_str":"41189933855158272","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41189933855158272,"from_user_id":120927161,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"228973151","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:36:59 +0000","from_user":"daisuke1589","id_str":"41189931887890432","metadata":{"result_type":"recent"},"to_user_id":null,"text":"twitter\u3063\u3066\u52dd\u624b\u306b\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u3082\u3044\u3044\u3093\u3060\u3063\u3051\uff1f","id":41189931887890432,"from_user_id":228973151,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"54314110","profile_image_url":"http://a2.twimg.com/profile_images/1193541240/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:57 +0000","from_user":"Alohazuki","id_str":"41189922668953600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u306e\u5e83\u5cf6\u5f01\u3082\u3042\u3063\u305f\u3093\u3060\u306d\u3002","id":41189922668953600,"from_user_id":54314110,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"72594681","profile_image_url":"http://a3.twimg.com/profile_images/1227240916/____normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:56 +0000","from_user":"uri4ichi","id_str":"41189916922744832","metadata":{"result_type":"recent"},"to_user_id":226852303,"text":"@7_fuka Twitter\u304b\u3076\u308c\u306f\u3001\u3059\u3050\u306bD\u306b\u8d70\u308b\u306e\u3067\u3002\u306a\u3093\u3060\u304b\u5fae\u7b11\u307e\u3057\u3044\u306e\u3067\u3059( \u2579\u25e1\u2579)","id":41189916922744832,"from_user_id":72594681,"to_user":"7_fuka","geo":null,"iso_language_code":"ja","to_user_id_str":"226852303","source":"<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>"},{"from_user_id_str":"168393854","profile_image_url":"http://a3.twimg.com/profile_images/1253554518/GuNp3xVS_normal","created_at":"Fri, 25 Feb 2011 17:36:55 +0000","from_user":"makonyanhime","id_str":"41189913701515264","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6589\u85e4\u3055\u3093\u3082\u30c0\u30e1\u3060...\u4eca\u591c\u306fTwitter\u5909\u3060\u306a\u3041(;_;)","id":41189913701515264,"from_user_id":168393854,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mobile.twitter.com" rel="nofollow">Twitter for Android</a>"},{"from_user_id_str":"122636787","profile_image_url":"http://a2.twimg.com/profile_images/1189607563/DSC01987_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:54 +0000","from_user":"enpy1217","id_str":"41189908500594688","metadata":{"result_type":"recent"},"to_user_id":null,"text":"twitter\u4e45\u3057\u3076\u308a\u306b\u958b\u3044\u305f\u3002\u3068\u3066\u3082\u591a\u5fd9\u3060\u3063\u305f\u3002\u75b2\u308c\u305f\u3002\u304a\u98a8\u5442\u306b\u3082\u5165\u308c\u306a\u304b\u3063\u305f\u3002\u30ad\u30bf\u30cd\u2026","id":41189908500594688,"from_user_id":122636787,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.flight.co.jp/iPhone/TweetMe/" rel="nofollow">TweetMe for iPhone</a>"},{"from_user_id_str":"81663694","profile_image_url":"http://a3.twimg.com/profile_images/1177576126/__normal.png","created_at":"Fri, 25 Feb 2011 17:36:51 +0000","from_user":"progmiya","id_str":"41189895494049792","metadata":{"result_type":"recent"},"to_user_id":94050844,"text":"@hirasai_skyhigh \u6674\u308c\u541b\u3002\u30cd\u30bf\u30d0\u30ec\u306f\u898b\u305f\u304f\u306a\u3044\u3051\u3069\u30012ch\u3082twitter\u3082\u3084\u308a\u305f\u3044\u306e\u304c\u4eba\u3068\u8a00\u3046\u3082\u306e\u3088","id":41189895494049792,"from_user_id":81663694,"to_user":"hirasai_skyhigh","geo":null,"iso_language_code":"ja","to_user_id_str":"94050844","source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"159237469","profile_image_url":"http://a3.twimg.com/profile_images/1140433484/______2_normal.png","created_at":"Fri, 25 Feb 2011 17:36:50 +0000","from_user":"hikari_juku","id_str":"41189892096532480","metadata":{"result_type":"recent"},"to_user_id":135634241,"text":"@sssukimasuky \n\u4f55\u304b\u3042\u3063\u305f\u98a8\u3067\u3059\u306d\uff08\u7b11\uff09\u3000\u78ba\u304b\u306bTwitter\u306f\u6c17\u8efd\u3067\u3059\u3057\u306d\u3002\u30e1\u30fc\u30eb\u306b\u306a\u308b\u3068\u30d5\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u91cd\u304f\u306a\u308b\u5834\u5408\u3082\u3042\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u306d\u3002\u305d\u3046\u8003\u3048\u308b\u3068\u3059\u3054\u3044\u6642\u4ee3\u3060\u3002","id":41189892096532480,"from_user_id":159237469,"to_user":"sssukimasuky","geo":null,"iso_language_code":"ja","to_user_id_str":"135634241","source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"141915990","profile_image_url":"http://a0.twimg.com/profile_images/1248969898/icon679566266564378764images_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:48 +0000","from_user":"adashino_","id_str":"41189886878949376","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41189886878949376,"from_user_id":141915990,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"111308629","profile_image_url":"http://a1.twimg.com/profile_images/1137421845/mmooton_normal.png","created_at":"Fri, 25 Feb 2011 17:36:46 +0000","from_user":"mmooton","id_str":"41189877940748288","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @minponjp: \u3010\u3064\u3076\u3084\u304f\u3060\u3051\u306710000\u5186\u5546\u54c1\u5238GET\u3011<<visa\u30ae\u30d5\u30c8\u30ab\u30fc\u30c910000\u5186\u5206\u3092\u6bce\u6708\u62bd\u9078\u3067\u30d7\u30ec\u30bc\u30f3\u30c8>> \u21d2\u8a73\u3057\u304f\u306f\u4e0b\u306e\uff35\uff32\uff2c\u3088\u308a\u2193\u2193\u2193\u2193\u2193 http://minpon.jp/user_data/twitter_campaign.php","id":41189877940748288,"from_user_id":111308629,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"140945098","profile_image_url":"http://a0.twimg.com/profile_images/1198948281/b7664c71-87bc-4187-9d46-a61ab8d41b96_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:46 +0000","from_user":"waruimayuko","id_str":"41189877122867200","metadata":{"result_type":"recent"},"to_user_id":113371008,"text":"@toumeisyoujyo \u3042\u3053\u3061\u3083\u3093Twitter\u3084\u3063\u3066\u305f\u306e\u306d\u3002\u307e\u3060\u304a\u5e2d\u3042\u308b\u305d\u3046\u306a\u306e\u3067\u662f\u975e\uff01","id":41189877122867200,"from_user_id":140945098,"to_user":"toumeisyoujyo","geo":null,"iso_language_code":"ja","to_user_id_str":"113371008","source":"<a href="http://twimi.jp/?r=via" rel="nofollow">twimi\u2606new</a>"},{"from_user_id_str":"167512527","profile_image_url":"http://a1.twimg.com/profile_images/1172286365/newspaper_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:45 +0000","from_user":"KoranKaget","id_str":"41189871775252480","metadata":{"result_type":"recent"},"to_user_id":null,"text":"http://bit.ly/93Eeud RT @motocentrism \u30d6\u30ed\u30b0\u8a18\u4e8b\u66f8\u304d\u307e\u3057\u305f\u30fc\uff1a MotoGP\u3000\u30d6\u30c3\u30af\u30e1\u30fc\u30ab\u30fc\u306b\u898b\u308b\u5404\u30e9\u30a4\u30c0\u30fc\u306e\u4e0b\u99ac\u8a55 - http://goo.gl/xVe6... http://bit.ly/hDYxyx @motogpudpate","id":41189871775252480,"from_user_id":167512527,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>"},{"from_user_id_str":"160251772","profile_image_url":"http://a3.twimg.com/profile_images/1150692471/_____normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:45 +0000","from_user":"keikochaki","id_str":"41189870781075456","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u300c\u305a\u3063\u3068twitter\u3084\u3063\u3066\u308b\u3088\u306d\u300d\u3068\u6012\u3089\u308c\u3066\u3057\u307e\u3063\u305f(\u82e6\u7b11)","id":41189870781075456,"from_user_id":160251772,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twtr.jp" rel="nofollow">Keitai Web</a>"},{"from_user_id_str":"211565766","profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default_profile_5_normal.png","created_at":"Fri, 25 Feb 2011 17:36:42 +0000","from_user":"sayap1yo","id_str":"41189858236043264","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u304a\u98df\u4e8b\u4f1a\u884c\u304d\u305f\u304b\u3063\u305f\u3051\u3069\n\u53cb\u9054\u3068\u904a\u3093\u3067\u307e\u3093\u305f\ue056\ue326\n\nTwitter\u898b\u3066\u307e\u3057\u305f\u3051\u3069\n\u3064\u3076\u3084\u304f\u30bf\u30a4\u30df\u30f3\u30b0\n\u5931\u3063\u3066\u305f\u3060\u3051\u3067\u3059( \u00b4 \u25bd ` )\uff89\u7b11","id":41189858236043264,"from_user_id":211565766,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.nibirutech.com" rel="nofollow">TwitBird</a>"},{"from_user_id_str":"19603191","profile_image_url":"http://a1.twimg.com/profile_images/1254077264/116_normal.gif","created_at":"Fri, 25 Feb 2011 17:36:40 +0000","from_user":"Purple_Flash","id_str":"41189851873157120","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @syu_thi_bot: \u3044\u3064\u307e\u3067Twitter\u3084\u3063\u3066\u308b\u3093\u3060\u3044\uff1f\u3044\u3044\u52a0\u6e1b\u73fe\u5b9f\u306b\u623b\u308a\u306a\u3088\u3002\u3053\u3053\u306f\u30ad\u30df\u305f\u3061\u4e09\u6b21\u5143\u306e\u4eba\u9593\u304c\u3044\u308b\u3079\u304d\u5834\u6240\u3058\u3083\u306a\u3044\u3093\u3060\u3088\u3002\u305d\u3093\u306a\u306e\u57fa\u672c\u3060\u308d\uff01\uff01","id":41189851873157120,"from_user_id":19603191,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"215930291","profile_image_url":"http://a0.twimg.com/profile_images/1247906106/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:30 +0000","from_user":"minori_millie","id_str":"41189810055938048","metadata":{"result_type":"recent"},"to_user_id":212972774,"text":"@c_c_chika \u7b11\u3063\u3066\u305d\u3046\u3060\u306a\u3063\u3066\u601d\u3063\u3066\u305f(o^^o)\u30c1\u30ab\u306e\u7b11\u3044\u58f0\u304c\u805e\u3053\u3048\u3066\u304d\u305f\u3082\u3093\u3002mail\u306bTwitter\u3067\u5927\u5fd9\u3057\u3084\u3002","id":41189810055938048,"from_user_id":215930291,"to_user":"c_c_chika","geo":null,"iso_language_code":"ja","to_user_id_str":"212972774","source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"},{"from_user_id_str":"197459334","profile_image_url":"http://a3.twimg.com/profile_images/1210698414/shiratorishoko_normal.png","created_at":"Fri, 25 Feb 2011 17:36:30 +0000","from_user":"SyokoShiratori","id_str":"41189809586311168","metadata":{"result_type":"recent"},"to_user_id":null,"text":"+0.90kg \u30c0\u30a4\u30a8\u30c3\u30c8\u5fdc\u63f4\u3057\u3066\u307e\u3059\u3002(*^^*)\u30c0\u30a4\u30a8\u30c3\u30c8\u4f53\u91cd\u5831\u544a\u306e\u3064\u3076\u3084\u304d\u3067\u3059\u3002 http://bit.ly/fhN2fM RT @hayayumi \u3053\u3093\u306a\u6642\u9593\u306b\u3084\u304d\u306b\u304f\u30fc\u266b\u30c0\u30a4\u30a8\u30c3\u30c8\u671f\u9593\u306a\u306e\u306b\u306d....","id":41189809586311168,"from_user_id":197459334,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mob-mc.com" rel="nofollow">\uff08\u4eee\u79f0\uff09\u30c4\u30a4\u30af\u30ea\u30c3\u30af twiclick</a>"},{"from_user_id_str":"12337665","profile_image_url":"http://a0.twimg.com/profile_images/1146194926/pixiv-icon_normal.png","created_at":"Fri, 25 Feb 2011 17:36:27 +0000","from_user":"t_a_k_i","id_str":"41189797364121600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Google\u30ea\u30fc\u30c0\u30fc\u3067\u30b5\u30a4\u30c8\u306e\u66f4\u65b0\u30c1\u30a7\u30c3\u30af\u3059\u308b\u3088\u308a\u3001Twitter\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u66f4\u65b0\u3092\u77e5\u308b\u307b\u3046\u304c\u4fbf\u5229\u3060\u306a\u3053\u308c","id":41189797364121600,"from_user_id":12337665,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>"},{"from_user_id_str":"104862453","profile_image_url":"http://a3.twimg.com/profile_images/1248609864/Image014_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:25 +0000","from_user":"yuz_ume","id_str":"41189787943714816","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @fuefukioyasumi: \u3082\u3046\u3044\u3044\u3002\u300c\u671d\u751f\u300d\u306a\u3093\u304b\u3044\u3044\u3002BBC\u3082CNN\u3082\u82f1\u8a9e\u653e\u9001\u3060\u3002\u307f\u3093\u306a\u3001\u30c6\u30ec\u30d3\u3092\u3076\u3061\u3063\u3068\u5207\u3063\u3066Twitter\u3092\u898b\u3088\u3046\u3002\u3053\u3053\u306b\u300c\u751f\u304d\u305f\u60c5\u5831\u300d\u304c\u6d41\u308c\u3066\u3044\u308b\u3002\u300c\u751f\u304d\u305f\u53eb\u3073\u300d\u304c\u3042\u308b\u3002\u3053\u3053\u304b\u3089\u3067\u3082\u6b74\u53f2\u306e\u8ee2\u63db\u70b9\u3092\u611f\u3058\u308b\u4e8b\u304c\u3067\u304d\u308b\u306e\u3060\u3002 @gjmorley #libjp","id":41189787943714816,"from_user_id":104862453,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"213846746","profile_image_url":"http://a1.twimg.com/profile_images/1242263342/haruhi1_normal.png","created_at":"Fri, 25 Feb 2011 17:36:23 +0000","from_user":"sloth888jpgame","id_str":"41189778409922560","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u643a\u5e2f\u96fb\u8a71\u7528\u306eTwitter\u3092\u5229\u7528\u3057\u305f\u30b2\u30fc\u30e0\u3092\u77e5\u3063\u3066\u3044\u308b\u4eba\u306f\u3001\u7d39\u4ecb\u3057\u3066\u304f\u3060\u3055\u3044\u3002 #TwitterGame","id":41189778409922560,"from_user_id":213846746,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"17484724","profile_image_url":"http://a2.twimg.com/profile_images/1138677235/iconue_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:22 +0000","from_user":"tsutcho","id_str":"41189777831231490","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30a2\u30aa\u30b7\u30de\u3055\u3093twitter\u306b\u7acb\u3064\u30fb\u30fb\u30fb\u3060\u3068\u30fb\u30fb\u30fb\uff1f\uff12\u756a\u76ee\u306e\u30d5\u30a9\u30ed\u30ef\u30fc\u306e\u5ea7\u3092\u3044\u305f\u3060\u3044\u3066\u304a\u3053\u3046","id":41189777831231490,"from_user_id":17484724,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"220041064","profile_image_url":"http://a1.twimg.com/sticky/default_profile_images/default_profile_0_normal.png","created_at":"Fri, 25 Feb 2011 17:36:21 +0000","from_user":"sloth888jp_bot5","id_str":"41189772521254914","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u6642\u3005\u3001TwiAll\uff08\u30c4\u30a4\u30aa\u30fc\u30eb\uff09\u3067Twitter\u306e\u81ea\u52d5\u30d5\u30a9\u30ed\u30fc\u30fb\u30d5\u30a9\u30ed\u30fc\u8fd4\u3057\u3092\u3057\u3066\u3044\u307e\u3059\u3002","id":41189772521254914,"from_user_id":220041064,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>"},{"from_user_id_str":"177693537","profile_image_url":"http://a0.twimg.com/profile_images/1240130924/20110207213206_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:21 +0000","from_user":"Na_Okinawa","id_str":"41189769912397824","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @ebizo66: \u30ea\u30d3\u30a2\u30fb\u30c8\u30ea\u30dd\u30ea\u306eTw\uff1a\u6551\u6025\u8eca\u304c\u6765\u305f\u304c\u3001\u8ca0\u50b7\u8005\u3092\u8eca\u5185\u3067\u6bba\u5bb3\u3057\u3066\u3044\u305f\u3001\u3068\u3002\uff08\u6ec5\u8336\u82e6\u8336\u3060\uff01\uff09http://ow.ly/43pQ2 #libjp","id":41189769912397824,"from_user_id":177693537,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>"},{"from_user_id_str":"147006592","profile_image_url":"http://a2.twimg.com/profile_images/1251306448/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:19 +0000","from_user":"takasu_rika","id_str":"41189763532865536","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @kihirokiro: Twitter\u3067\u30cd\u30bf\u30d0\u30ec\u4e91\u3005\u3044\u3063\u3066\u3082\u5143\u3005Twitter\u3063\u3066\u300c\u500b\u4eba\u306e\u72ec\u308a\u8a00\u300d\u3060\u308d","id":41189763532865536,"from_user_id":147006592,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>"},{"from_user_id_str":"100239985","profile_image_url":"http://a1.twimg.com/profile_images/733461294/CIMG0207_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:19 +0000","from_user":"strangebarjun","id_str":"41189762182152192","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u3092\u59cb\u3081\u3066\u3001\u305d\u308d\u305d\u308d\u4e00\u5e74\u306b\u306a\u308a\u307e\u3059\u3002\u632f\u308a\u8fd4\u308b\u3068\u3001\u307c\u304f\u306e\u4eba\u9593\u6027\u3092\u305d\u3063\u304f\u308a\u53cd\u6620\u3059\u308b\u304c\u5982\u304f\u3001\u534a\u7aef\u3067\u3059\u306d\u3002\u60c5\u5831\u53ce\u96c6\u30c4\u30fc\u30eb\u3001\u60c5\u5831\u767a\u4fe1\u30c4\u30fc\u30eb\u3001\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3\u30c4\u30fc\u30eb\u3001\u3069\u308c\u3082\u6a5f\u80fd\u3057\u5207\u308c\u3066\u3044\u306a\u3044\u306a\u3042\u3001\u3068\u3002\u305d\u3057\u3066\u3042\u308b\u306e\u306f\u300c\u3069\u3053\u304b\u3089\u3082\u76f8\u624b\u306b\u3055\u308c\u3066\u3044\u306a\u3044\u300d\u3068\u3044\u3046\u3001\u65e2\u77e5\u306e\u73fe\u5b9f\u3067\u3059\u3002","id":41189762182152192,"from_user_id":100239985,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>"},{"from_user_id_str":"126390384","profile_image_url":"http://a2.twimg.com/profile_images/1176065038/nemunemu_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:18 +0000","from_user":"gesukapper","id_str":"41189757476286464","metadata":{"result_type":"recent"},"to_user_id":80935865,"text":"@tatsugorou \u306a\u3093\u304b\u4e16\u306e\u4e2d\u306b\u306f\u611a\u75f4\u3082\u4e0b\u30cd\u30bf\u3082\u8a00\u3044\u653e\u984c\u306etwitter\u3068\u3044\u3046\u3082\u306e\u304c\u3042\u308b\u305d\u3046\u3067\u3059\u3002","id":41189757476286464,"from_user_id":126390384,"to_user":"tatsugorou","geo":null,"iso_language_code":"ja","to_user_id_str":"80935865","source":"<a href="http://janetter.net/" rel="nofollow">Janetter</a>"},{"from_user_id_str":"196059029","profile_image_url":"http://a1.twimg.com/profile_images/1208831726/ruka2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:17 +0000","from_user":"luka_m_bot","id_str":"41189756666777600","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u308f\u305f\u3057\u3082twitter\u306f\u3058\u3081\u307e\u3057\u305f","id":41189756666777600,"from_user_id":196059029,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://www24.atpages.jp/aoi2/bot.php" rel="nofollow">\u5de1\u308b\u97f3</a>"},{"from_user_id_str":"88135613","profile_image_url":"http://a3.twimg.com/profile_images/1088552877/P9280150_normal.JPG","created_at":"Fri, 25 Feb 2011 17:36:14 +0000","from_user":"Roko38","id_str":"41189740321587200","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\uff46\uff42\u306b\u30ed\u30b0\u30a4\u30f3\u3059\u308b\u6a5f\u4f1a\u304c\u65e5\u306b\u65e5\u306b\u5897\u3048\u3066\u304d\u305f\uff3e\uff3e \u6163\u308c\u3066\u304f\u308b\u3068\u3042\u3063\u3061\u306e\u304c\u9762\u767d\u3044\uff06\u4f7f\u3044\u52dd\u624b\u304c\u3044\u3044\u3088\u3046\u306a\u6c17\u304c\u3059\u308b\u3002\u8907\u5408\u7684\u306b\u8272\u3005\u51fa\u6765\u307e\u3059\u3088\u306d\u2026\u3063\u3066\u3001\u601d\u3063\u305f\u3053\u3068\u3092\u545f\u304f\u306e\u306fTwitter\u3060\u3063\u305f\u308a\u3067\u3059\u304c\u2026(^_^; \u305d\u3057\u3066\u81ea\u5206\u306e\u5834\u5408\u306f\u30c4\u30a4\u3068\u9023\u52d5\u3057\u3065\u3089\u3044\u72b6\u6cc1\u3060\u3063\u305f\u308a\u3067\u2026\u3002","id":41189740321587200,"from_user_id":88135613,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"110825211","profile_image_url":"http://a2.twimg.com/profile_images/1108977866/o_t_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:12 +0000","from_user":"kou_nanjyo","id_str":"41189731941363712","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @x68k: \u57fa\u672c\u7684\u306bTwitter\u4e0a\u3067\u306f"\u597d\u304d\u306b\u3084\u308c\u3070\u3044\u3044"\u3060\u3051\u3069\u3001\u540d\u524d\u3082\u30a2\u30a4\u30b3\u30f3\u3082\u30a2\u30f3\u30bf\u3058\u3083\u306a\u3044\u305f\u304f\u3055\u3093\u306e\u4eba\u305f\u3061\u306e\u9b42\u304c\u3053\u3082\u3063\u305f\u3082\u306e\u306a\u306e\u3060\u304b\u3089\u3001\u305d\u308c\u3060\u3051\u306f"\u80cc\u8ca0\u3048"\u3068\u601d\u3046\uff1e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8","id":41189731941363712,"from_user_id":110825211,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://tweetlogix.com" rel="nofollow">Tweetlogix</a>"},{"from_user_id_str":"2095960","profile_image_url":"http://a2.twimg.com/profile_images/1248999075/majiresu2_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:10 +0000","from_user":"guldeen","id_str":"41189726945947648","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3042\u308a\u3083\u307e\u3041\u3002\u25bchttp://bit.ly/et4vVa \uff3b\u89d2\u5ddd\u66f8\u5e97\uff3d\u300c\u30b6\u30fb\u30b9\u30cb\u30fc\u30ab\u30fc\u300d\u4f11\u520a\u3078\u3000\u300c\u6dbc\u5bae\u30cf\u30eb\u30d2\u300d\u751f\u3093\u3060\u30e9\u30ce\u30d9\u96d1\u8a8c18\u5e74\u3067\u5e55 via http://twitter.com/lkj777","id":41189726945947648,"from_user_id":2095960,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/">web</a>"},{"from_user_id_str":"164121549","profile_image_url":"http://a1.twimg.com/profile_images/1251758789/m_108-07ae3_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:09 +0000","from_user":"hachi_touhi","id_str":"41189719299727360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u30cd\u30bf\u30d0\u30ec\u6c17\u306b\u3057\u3066\u305f\u3089Twitter\u3084\u3063\u3066\u3089\u308c\u306a\u3044ww","id":41189719299727360,"from_user_id":164121549,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twicca.r246.jp/" rel="nofollow">twicca</a>"},{"from_user_id_str":"194494659","profile_image_url":"http://a3.twimg.com/profile_images/1249717822/image_normal.jpg","created_at":"Fri, 25 Feb 2011 17:36:08 +0000","from_user":"tomonattomo","id_str":"41189715415801856","metadata":{"result_type":"recent"},"to_user_id":null,"text":"\u3046\u308f\u3001\u660e\u65e5\u671d\u304b\u3089\u30d0\u30a4\u30c8\u3084\u306e\u306b\u306a\u3093\u3060\u3053\u306e\u306d\u3075\u304b\u3057\u3002\u3042\u3001\u591c\u66f4\u304b\u3057\u3002\u30d1\u30d4\u30eb\u30b9\u3068BUMP\u3001\u3048\u307f\u3068Twitter\u306eDM\u3057\u3059\u304e\u305f\u306a\u2026","id":41189715415801856,"from_user_id":194494659,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://mixi.jp/promotion.pl?id=voice_twitter" rel="nofollow"> mixi \u30dc\u30a4\u30b9 </a>"},{"from_user_id_str":"97224364","profile_image_url":"http://a3.twimg.com/profile_images/1150074355/fb8bcca60d340862c053a756377bfae8_normal.jpeg","created_at":"Fri, 25 Feb 2011 17:36:06 +0000","from_user":"xxxheat","id_str":"41189709174677504","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Twitter\u5b8c\u5168\u306b\u30d0\u30b0\u3063\u3066\u308borz","id":41189709174677504,"from_user_id":97224364,"geo":null,"iso_language_code":"ja","to_user_id_str":null,"source":"<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>"}],"max_id":41190705623732224,"since_id":38643906774044672,"refresh_url":"?since_id=41190705623732224&q=twitter","next_page":"?page=2&max_id=41190705623732224&rpp=100&lang=ja&q=twitter","results_per_page":100,"page":1,"completed_in":0.093336,"warning":"adjusted since_id to 38643906774044672 (), requested since_id was older than allowed -- since_id removed for pagination.","since_id_str":"38643906774044672","max_id_str":"41190705623732224","query":"twitter"}
+ test/json-data/unicode_2705.json view
@@ -0,0 +1,1 @@+"\u2705"
waargonaut.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.5.2.2+version: 0.6.0.0 -- A short (one-line) description of the package. synopsis: JSON wrangling@@ -42,15 +42,29 @@ -- README. extra-source-files: changelog.md , README.md++ -- Misc json files , test/json-data/numbers.json- , test/json-data/test1.json- , test/json-data/test2.json- , test/json-data/test3.json- , test/json-data/test4.json- , test/json-data/test5.json- , test/json-data/test6.json- , test/json-data/test7.json+ , test/json-data/image_obj.json+ , test/json-data/twitter_with_hex_vals.json+ , test/json-data/unicode_2705.json + -- Known bad json files+ , test/json-data/bad-json/no_comma_arr.json+ , test/json-data/bad-json/no_comma_obj.json++ -- Golden files+ , test/json-data/goldens/backslash128.json.golden+ , test/json-data/goldens/empty_arr_empty_ws.json.golden+ , test/json-data/goldens/image_obj.json.golden+ , test/json-data/goldens/location_array.json.golden+ , test/json-data/goldens/nested_arrs.json.golden+ , test/json-data/goldens/null_arr_trailing_comma_ws.json.golden+ , test/json-data/goldens/numbers.json.golden+ , test/json-data/goldens/twitter100.json.golden+ , test/json-data/goldens/twitter_with_hex_vals.json.golden+ , test/json-data/goldens/unicode_2705.json.golden+ homepage: https://github.com/qfpl/waargonaut bug-reports: https://github.com/qfpl/waargonaut/issues @@ -74,10 +88,20 @@ library -- Modules included in this executable, other than Main. exposed-modules: Waargonaut.Types.Whitespace++ , Waargonaut.Types.CommaSep.Elem+ , Waargonaut.Types.CommaSep.Elems , Waargonaut.Types.CommaSep++ , Waargonaut.Types.JChar.HexDigit4+ , Waargonaut.Types.JChar.Escaped+ , Waargonaut.Types.JChar.Unescaped , Waargonaut.Types.JChar- , Waargonaut.Types.JArray++ , Waargonaut.Types.JObject.JAssoc , Waargonaut.Types.JObject++ , Waargonaut.Types.JArray , Waargonaut.Types.JString , Waargonaut.Types.JNumber , Waargonaut.Types.Json@@ -87,8 +111,20 @@ , Waargonaut.Decode.ZipperMove , Waargonaut.Decode.Error , Waargonaut.Decode.Types+ , Waargonaut.Decode.Runners+ , Waargonaut.Encode.Types + , Waargonaut.Encode.Builder.JChar+ , Waargonaut.Encode.Builder.Whitespace+ , Waargonaut.Encode.Builder.JString+ , Waargonaut.Encode.Builder.JNumber+ , Waargonaut.Encode.Builder.JObject+ , Waargonaut.Encode.Builder.JArray+ , Waargonaut.Encode.Builder.CommaSep+ , Waargonaut.Encode.Builder.Types+ , Waargonaut.Encode.Builder+ , Waargonaut.Decode , Waargonaut.Decode.Traversal @@ -98,42 +134,47 @@ , Waargonaut.Test , Waargonaut.Prettier + , Waargonaut.Attoparsec+ , Waargonaut.Lens+ , Waargonaut ghc-options: -Wall -- Other library packages from which modules are imported.- build-depends: base >= 4.9 && < 4.13- , lens >= 4.15 && < 4.18- , mtl >= 2.2.2 && < 2.3- , text >= 1.2 && < 1.3- , bytestring >= 0.10.6 && < 0.11- , parsers >= 0.12 && < 0.13- , digit >= 0.7 && < 0.8- , semigroups >= 0.8.4 && < 0.19- , scientific >= 0.3 && < 0.4- , distributive >= 0.5 && < 0.7- , nats >= 1 && <1.2- , zippers >= 0.2 && < 0.3- , vector >= 0.12 && < 0.13- , errors >= 2.2 && < 2.4- , hoist-error >= 0.2 && < 0.3- , containers >= 0.5.6 && < 0.7- , witherable >= 0.2 && < 0.4- , generics-sop >= 0.4 && < 0.5- , mmorph >= 1.1 && < 1.2- , transformers >= 0.4 && < 0.6- , bifunctors >= 5 && < 5.6- , contravariant >= 1.4 && < 1.6- , wl-pprint-annotated >= 0.1 && < 0.2- , hw-json >= 0.9.0.1 && < 0.10- , hw-prim >= 0.6 && < 0.7- , hw-balancedparens >= 0.2 && < 0.3- , hw-rankselect >= 0.10 && < 0.13- , hw-bits >= 0.7 && < 0.8- , tagged >= 0.8.5 && < 0.9- , semigroupoids >= 5.2.2 && < 5.4- , natural >= 0.3 && < 0.4+ build-depends: base >= 4.9 && < 4.13+ , lens >= 4.15 && < 4.18+ , mtl >= 2.2.2 && < 2.3+ , text >= 1.2 && < 1.3+ , bytestring >= 0.10.6 && < 0.11+ , parsers >= 0.12 && < 0.13+ , digit >= 0.7 && < 0.8+ , semigroups >= 0.8.4 && < 0.19+ , scientific >= 0.3 && < 0.4+ , distributive >= 0.5 && < 0.7+ , nats >= 1 && <1.2+ , zippers >= 0.2 && < 0.3+ , vector >= 0.12 && < 0.13+ , errors >= 2.2 && < 2.4+ , hoist-error >= 0.2 && < 0.3+ , containers >= 0.5.6 && < 0.7+ , witherable >= 0.2 && < 0.4+ , generics-sop >= 0.4 && < 0.5+ , mmorph >= 1.1 && < 1.2+ , transformers >= 0.4 && < 0.6+ , bifunctors >= 5 && < 5.6+ , contravariant >= 1.4 && < 1.6+ , wl-pprint-annotated >= 0.1 && < 0.2+ , hw-json >= 0.9.0.1 && < 0.10+ , hw-prim >= 0.6 && < 0.7+ , hw-balancedparens >= 0.2 && < 0.3+ , hw-rankselect >= 0.10 && < 0.13+ , hw-bits >= 0.7 && < 0.8+ , tagged >= 0.8.5 && < 0.9+ , semigroupoids >= 5.2.2 && < 5.4+ , natural >= 0.3 && < 0.4+ , unordered-containers >= 0.2.9 && < 0.3+ , attoparsec >= 0.13 && < 0.15 -- Directories containing source files. hs-source-dirs: src@@ -170,6 +211,8 @@ , Types.Json , Types.Whitespace + , Properties+ , Golden , Laws , Utils , Encoder@@ -206,9 +249,12 @@ , containers >= 0.5.6 && < 0.7 , natural >= 0.3 && < 0.4 , contravariant >= 1.4 && < 1.6+ , filepath >= 1.4 && < 1.5+ , tasty-golden >= 2.3 && < 2.4+ , unordered-containers >= 0.2.9 && < 0.3 , waargonaut - ghc-options: -Wall+ ghc-options: -Wall -O2 default-language: Haskell2010